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