c # ref для скорости - PullRequest
       4

c # ref для скорости

0 голосов
/ 01 марта 2011

Я понимаю полное слово ref в .NET

Так как использование той же переменной увеличит скорость, чтобы использовать ref вместо копирования?

Я нахожу узкое место в общем пароле.

Вот мои коды

protected internal string GetSecurePasswordString(string legalChars, int length)
{
    Random myRandom = new Random();
    string myString = "";
    for (int i = 0; i < length; i++)
    {
        int charPos = myRandom.Next(0, legalChars.Length - 1);
        myString = myString + legalChars[charPos].ToString();
    }
    return myString;
}

лучше сослаться перед легальными символами?

Ответы [ 4 ]

9 голосов
/ 01 марта 2011

Передача строки по значению не копирует строку. Он только копирует ссылку на строку. Повышение производительности при передаче строки по ссылке, а не по значению.

5 голосов
/ 01 марта 2011

Нет, вы не должны передавать ссылку на строку на ссылку .

Однако вы создаете несколько строк бессмысленно.Если вы создаете длинные пароли, это может быть узким местом.Вот более быстрая реализация:

protected internal string GetSecurePasswordString(string legalChars, int length)
{
    Random myRandom = new Random();
    char[] chars = new char[length];
    for (int i = 0; i < length; i++)
    {
        int charPos = myRandom.Next(0, legalChars.Length - 1);
        chars[i] = legalChars[charPos];
    }
    return new string(chars);
}

Однако у него все еще есть три больших недостатка:

  • Каждый раз он создает новый экземпляр Random.Если вы вызовете этот метод дважды подряд, вы получите один и тот же пароль дважды.Плохая идея.
  • Верхняя граница, указанная в вызове Random.Next(), является эксклюзивной, поэтому вы никогда не будете использовать последний символ legalChars.
  • . Используется System.Random, то естьникоим образом не должен быть криптографически безопасным.Учитывая, что это предназначено для «безопасного пароля», вы должны рассмотреть что-то вроде System.Security.Cryptography.RandomNumberGenerator.Это больше работы, потому что API сложнее, но в итоге вы получите более безопасную систему (если вы все сделаете правильно).

Возможно, вы захотите использовать SecureString , если вы получаете действительно параноик.

0 голосов
/ 20 марта 2012

Слово об общем выигрыше в производительности при передаче строки ByReference ("ref") вместо ByValue:

Прирост производительности, но он очень маленький!

Рассмотрим программу ниже, где функция вызывается 10.000.0000 раз со строковым аргументом по значению и по ссылке.Среднее измеренное время составило

ByValue: 249 миллисекунд

ByReference: 226 миллисекунд

В общем случае "ref" являетсянемного быстрее, но часто об этом не стоит беспокоиться.

Вот мой код:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;

namespace StringPerformanceTest
{
    class Program
    {
        static void Main(string[] args)
        {
            const int n = 10000000;
            int k;
            string time, s1;
            Stopwatch sw;

            // List for testing ("1", "2", "3" ...)
            List<string> list = new List<string>(n);
            for (int i = 0; i < n; i++)
                list.Add(i.ToString());

            // Test ByVal
            k = 0;
            sw = Stopwatch.StartNew();

            foreach (string s in list)
            {
                s1 = s;
                if (StringTestSubVal(s1)) k++;
            }

            time = GetElapsedString(sw);
            Console.WriteLine("ByVal: " + time);
            Console.WriteLine("123 found " + k + " times.");


            // Test ByRef
            k = 0;
            sw = Stopwatch.StartNew();

            foreach (string s in list)
            {
                s1 = s;
                if (StringTestSubRef(ref s1)) k++;
            }

            time = GetElapsedString(sw);
            Console.WriteLine("Time ByRef: " + time);
            Console.WriteLine("123 found " + k + " times.");
        }

        static bool StringTestSubVal(string s)
        {
            if (s == "123")
                return true;
            else
                return false;
        }

        static bool StringTestSubRef(ref string s)
        {
            if (s == "123")
                return true;
            else
                return false;
        }

        static string GetElapsedString(Stopwatch sw)
        {
            if (sw.IsRunning) sw.Stop();
            TimeSpan ts = sw.Elapsed;
            return String.Format("{0:00}:{1:00}:{2:00}.{3:000}", ts.Hours, ts.Minutes, ts.Seconds, ts.Milliseconds);
        }

    }
}
0 голосов
/ 01 марта 2011

строк в .Net являются неизменяемыми, поэтому все операции изменения над строками всегда приводят к созданию (и сборке мусора) новых строк.В этом случае увеличение производительности не будет достигнуто при использовании ref.Вместо этого используйте StringBuilder.

...