C#随机数

C#随机数,c#,random,C#,Random,我正在做一个项目,我需要生成8个随机数。我有一个问题与随机数部分是非常耗时的某些原因。我所说的8个随机数的意思是,我需要一个由数字0-9组成的8个字符长的字符串。示例01234567或23716253等 我尝试了8次循环,用random.Next(0,9)生成一个随机数,然后将它们转换成一个字符串,并将它们连接到最后一个字符串。我还尝试使用random.Next(099999999)生成一个随机数,然后将该数转换为字符串,并用0填充为8 看起来两者都很慢,我需要想出一个更快的方法。我不介意打电话

我正在做一个项目,我需要生成8个随机数。我有一个问题与随机数部分是非常耗时的某些原因。我所说的8个随机数的意思是,我需要一个由数字0-9组成的8个字符长的字符串。示例01234567或23716253等

我尝试了8次循环,用random.Next(0,9)生成一个随机数,然后将它们转换成一个字符串,并将它们连接到最后一个字符串。我还尝试使用random.Next(099999999)生成一个随机数,然后将该数转换为字符串,并用0填充为8

看起来两者都很慢,我需要想出一个更快的方法。我不介意打电话给其他语言或其他东西,如果这有助于提高性能的话

这里有一些额外的信息要添加。我想我不会找到任何超高效的东西。我必须生成这个数字大约50000次。当我用47000进行测试时,花了8:39秒。每次只有0.011秒,但它只是减慢了速度,因为我也在使用has表。我还调用了hashtable.ContainsKey(),总共调用了47000次,总共只花了58秒。这真是太大的不同了

这是我最初使用的代码。 转换.ToString(rg.Next(099999999)).PadLeft(8,'0')

下面是一些代码来尝试解决这个问题。这是我得到的时间 包含值:00:00:00.4287102 包含键:00:01:12.2539062 生成密钥:00:08:24.2832039 地址:00:00:00

        TimeSpan containsValue = new TimeSpan();
        TimeSpan containsKey = new TimeSpan();
        TimeSpan generateCode = new TimeSpan();
        TimeSpan addCode = new TimeSpan();

        StreamReader sr = new StreamReader(txtDictionaryFile.Text);
        string curWord = sr.ReadLine().ToUpper();
        int i = 1;
        DateTime start;
        DateTime end;
        while (!sr.EndOfStream)
        {
            start = DateTime.Now;
            bool exists = mCodeBook.ContainsValue(curWord);
            end = DateTime.Now;
            containsValue += end - start;
            if (!exists)
            {
                string newCode;
                bool kExists;
                do
                {
                    start = DateTime.Now;
                    Random rnd = new Random(); 
                    StringBuilder builder = new StringBuilder(8); 
                    byte[] b = new byte[8]; 
                    rnd.NextBytes(b); 
                    for (int i = 0; i < 8; i++) 
                    { 
                        builder.Append((char)((b[i] % 10) + 48)); 
                    } 
                    newCode = builder.ToString();
                    end = DateTime.Now;
                    generateCode += end - start;

                    start = DateTime.Now;
                    kExists = mCodeBook.ContainsKey(newCode);
                    end = DateTime.Now;

                    containsKey += end - start;
                }
                while (kExists);

                start = DateTime.Now;
                mCodeBook.Add(newCode, curWord);
                end = DateTime.Now;

                addCode += start - end;
            }
            i++;
            curWord = sr.ReadLine().ToUpper();
        }
TimeSpan containsValue=new TimeSpan();
TimeSpan containsKey=新的TimeSpan();
TimeSpan generateCode=新的TimeSpan();
TimeSpan addCode=新的TimeSpan();
StreamReader sr=新的StreamReader(txtDictionaryFile.Text);
字符串curWord=sr.ReadLine().ToUpper();
int i=1;
日期时间开始;
日期时间结束;
而(!sr.EndOfStream)
{
start=DateTime.Now;
bool exists=mCodeBook.ContainsValue(curWord);
end=DateTime.Now;
containsValue+=结束-开始;
如果(!存在)
{
字符串新代码;
布尔马克思主义者;
做
{
start=DateTime.Now;
随机rnd=新随机();
StringBuilder=新的StringBuilder(8);
字节[]b=新字节[8];
下一个字节(b);
对于(int i=0;i<8;i++)
{ 
附加((字符)((b[i]%10)+48));
} 
newCode=builder.ToString();
end=DateTime.Now;
generateCode+=结束-开始;
start=DateTime.Now;
kExists=mCodeBook.ContainsKey(newCode);
end=DateTime.Now;
containsKey+=结束-开始;
}
而(马克思主义者);
start=DateTime.Now;
添加(新代码,curWord);
end=DateTime.Now;
addCode+=开始-结束;
}
i++;
curWord=sr.ReadLine().ToUpper();
}

你说你试过的东西都不应该“慢”。也许发布一些代码可以帮助我们找到问题所在。另外,慢的验收标准是什么


有一件事您似乎没有尝试过,那就是调用Random。接下来,您可以保证返回的数字长度为8个字符:Random。接下来(10000000,100000000)。

这应该非常有效。它分配一个八个字符的缓冲区并向其中添加字符。没有额外的步骤将每个数字转换为字符串并连接字符串,字符直接放在缓冲区中。然后以字符串的形式返回缓冲区,因此从缓冲区创建字符串也没有额外的步骤:

StringBuilder builder = new StringBuilder(8);
for (int i = 0; i < 8; i++) {
   builder.Append((char)rnd.Next(48,58));
}
string code = builder.ToString();
StringBuilder=新的StringBuilder(8);
对于(int i=0;i<8;i++){
Append((char)rnd.Next(48,58));
}
字符串代码=builder.ToString();
将单个随机数转换为字符串的优点是只调用随机生成器一次。您可以通过自己将其转换为字符串来加快转换速度:

StringBuilder builder = new StringBuilder(8);
int num = rnd.Next(0, 100000000);
for (int i = 0; i < 8; i++) {
   builder.Append((char)((num % 10) + 48));
   num /= 10;
}
string code = builder.ToString();
StringBuilder=新的StringBuilder(8);
int num=rnd.Next(0,100000000);
对于(int i=0;i<8;i++){
追加((char)((num%10)+48));
num/=10;
}
字符串代码=builder.ToString();

(请注意,下一个方法的第二个参数不包含在内,因此它应该是100000000而不是9999999。这个数字实际上是以这种方式向后呈现到字符串中的,但这并不重要,因为它是一个随机数。)

与Guffa的答案类似,但在纳米级上可能更快,因为它避免了“昂贵”的除法

Random rnd=new Random();
StringBuilder=新的StringBuilder(8);
字节[]b=新字节[8];
下一个字节(b);
对于(int i=0;i<8;i++)
{
附加((字符)((b[i]%10)+48));
}
字符串代码=builder.ToString();

在您描述的场景中,字符串操作占用的时间可能与对Random.Next()的调用占用的时间相同或更多。我没有测试这些库,但是将二进制随机数转换为十进制字符串可能比生成它慢得多。当您逐个字符生成字符串时,情况更可能是这样


因此,如果可能的话,把数字保留为int,然后只转换为显示目的。

< P>我决定要打败Guffa:我怀疑他的版本有太多间接性。因此,他的解决方案有一个变体,它使用字符数组而不是stringbuilder。在他的快速解决方案中,当
        Random rnd = new Random();
        StringBuilder builder = new StringBuilder(8);
        byte[] b = new byte[8];
        rnd.NextBytes(b);
        for (int i = 0; i < 8; i++)
        {
            builder.Append((char)((b[i] % 10) + 48));
        }
        string code = builder.ToString();
char[] fauxbuilder = new char[8];
int num = rnd.Next(0, 100000000);
for (int i = 0; i < 8; i++)
{
    fauxbuilder[i] = (char)((num % 10) + 48);
    num /= 10;
}
string code = new string(fauxbuilder);
#define StopTime
using System;
using System.Diagnostics;

class C
{
  static void Main() {
    Random rg = new Random();
#if StopTime
    Stopwatch stopTime = new Stopwatch();
#else
    TimeSpan time = TimeSpan.Zero;
#endif
    for(int i=0;i<1000000;++i) {
#if StopTime
      stopTime.Start();
#else
      DateTime start = DateTime.Now;
#endif
      Convert.ToString(rg.Next(0, 99999999)).PadLeft(8, '0');
#if StopTime
      stopTime.Stop();
#else
      DateTime end = DateTime.Now;
      time += end - start;
#endif
    }
#if StopTime
    Console.WriteLine(stopTime.Elapsed);
#else
    Console.WriteLine(time);
#endif
  }
}
Testing: Guffa1
00:00:05.2472507
Testing: Guffa2
00:00:03.6620228
Testing: Simple
00:00:03.7890637
Testing: Brian
00:00:01.8473002
Testing: JohnDagg
00:00:03.8853139
Testing: chsh
00:00:05.9960557
using System;
using System.Text;
using System.Diagnostics;

class C
{
  const int IterationCount = 10000000;

  static void Main() {
    Test("Guffa1", Guffa1);
    Test("Guffa2", Guffa2);
    Test("Simple", Simple);
    Test("Brian", Brian);
    Test("JohnDagg", JohnDagg);
    Test("chsh", chsh);
  }

  delegate string TestDelegate(Random rg);

  private static void Test(string name, TestDelegate testMethod) {
    Console.WriteLine("Testing: " + name);
    Random rg = new Random(0);//Start each test with the same random seed

    //Call the method once outside of the test to make sure the JIT has run etc.
    for(int i=0;i<1000000;++i) {
      testMethod(rg);
    }
    Stopwatch timer = new Stopwatch();
    timer.Start();
    for(int i=0;i<IterationCount;++i) {
      testMethod(rg);
    }
    timer.Stop();
    Console.WriteLine(timer.Elapsed);
  }

  private static string Simple(Random rg) {
    return Convert.ToString(rg.Next(0, 99999999)).PadLeft(8, '0');
  }

  private static string Brian(Random rg) {
    char[] fauxbuilder = new char[8];
    int num = rg.Next(0, 100000000);
    for (int i = 0; i < 8; i++) {
      fauxbuilder[i] = (char)((num % 10) + 48);
      num /= 10;
    }
    return new string(fauxbuilder);
  }

  private static string Guffa1(Random rg) {
    StringBuilder builder = new StringBuilder(8);
    for (int i = 0; i < 8; i++) {
      builder.Append((char)rg.Next(48,58));
    }
    return builder.ToString();
  }

  private static string Guffa2(Random rg) { 
    StringBuilder builder = new StringBuilder(8);
    int num = rg.Next(0, 100000000);
    for (int i = 0; i < 8; i++) {
      builder.Append((char)((num % 10) + 48));
      num /= 10;
    }
    return builder.ToString();
  }

  private static string JohnDagg(Random rg) {
    StringBuilder builder = new StringBuilder(8);
    byte[] b = new byte[8];
    rg.NextBytes(b);
    for (int i = 0; i < 8; i++) {
      builder.Append((char)((b[i] % 10) + 48));
    }
    return builder.ToString();
  }

  private static string chsh(Random rg) {
    return (
      NextSpecial(rg, 10000000) +
      NextSpecial(rg, 1000000) +
      NextSpecial(rg, 100000) +
      NextSpecial(rg, 10000) +
      NextSpecial(rg, 1000) +
      NextSpecial(rg, 100) +
      NextSpecial(rg, 10) +
      NextSpecial(rg, 1))
      .ToString().PadLeft(8,'0');
  }

  static int NextSpecial(Random rg, int multiplier) {
    return rg.Next(0, 10) * multiplier;
  }   
}
    static Random rand = new Random();

    static int NextSpecial(this Random r, int multiplier)
    {
        return r.Next(0, 10) * multiplier;
    }

    static string randomString()
    {
        return (rand.NextSpecial(10000000) +
               rand.NextSpecial(1000000) +
               rand.NextSpecial(100000) +
               rand.NextSpecial(10000) +
               rand.NextSpecial(1000) +
               rand.NextSpecial(100) +
               rand.NextSpecial(10) +
               rand.NextSpecial(1))
               .ToString().PadLeft(8,'0');
    }

    static void Main()
    {
        int MAXITEMS = 1000000;
        IList<string> numbers = new List<string>(MAXITEMS);
        Stopwatch sw = new Stopwatch();
        sw.Start();
        for (int i = 0; i < MAXITEMS; i++)
        {
            numbers.Add(randomString());
        }
        sw.Stop();

        Console.WriteLine("{0} iterations took: {1}", MAXITEMS.ToString(), sw.Elapsed);

        File.WriteAllLines(@"c:\test.txt", numbers.ToArray());
        Console.ReadLine();
    }