0

.NETのrefワードを完全に理解しています

同じ変数を使用しているので、コピーを作成する代わりに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;
}

Legalcharsの前に参照する方が良いですか?

4

4 に答える 4

9

文字列を値で渡すと、文字列はコピーされません。文字列への参照のみをコピーします。値ではなく参照によって文字列を渡すことによるパフォーマンス上の利点はありません。

于 2011-03-01T20:27:43.040 に答える
5

いいえ、文字列参照参照で渡さないでください。

ただし、無意味にいくつかの文字列を作成しています。長いパスワードを作成している場合は、それがボトルネックになる可能性があります。より高速な実装は次のとおりです。

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);
}

ただし、まだ3つの大きな欠陥があります。

  • Random毎回の新しいインスタンスを作成します。このメソッドを2回続けて呼び出すと、同じパスワードを2回取得します。悪いアイデア。
  • 呼び出しで指定された上限Random.Next()は排他的であるため、の最後の文字を使用することはありませんlegalChars
  • を使用しますがSystem.Random、これは暗号的に安全であることを意味するものではありません。これは「安全なパスワード」のためのものであることを考えると、のようなものの使用を検討する必要がありますSystem.Security.Cryptography.RandomNumberGenerator。APIが難しいため、これを行うのはより手間がかかりますが、最終的にはより安全なシステムになります(適切に実行した場合)。

本当にパラノイアになった場合は、SecureStringの使用を検討することもできます。

于 2011-03-01T20:29:18.687 に答える
0

.Netの文字列は不変であるため、文字列に対するすべての変更操作により、常に新しい文字列が作成(およびガベージコレクション)されます。この場合、refを使用してもパフォーマンスは向上しません。代わりに、StringBuilderを使用してください。

于 2011-03-01T20:31:42.043 に答える
0

ByValueの代わりに文字列ByReference( "ref")を渡すことによる一般的なパフォーマンスの向上について一言:

パフォーマンスは向上しますが、非常に小さいです。

関数が値と参照によって文字列引数を使用して10.000.0000回呼び出される以下のプログラムについて考えてみます。測定された平均時間は

ByValue:249ミリ秒

参照: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);
        }

    }
}
于 2012-03-20T16:29:19.850 に答える