我想生成一百万比特的随机二进制文件,但是我的问题是代码需要花费大量时间,并且无法执行为什么会发生这种情况?
string result1 = "";
Random rand = new Random();
for (int i = 0; i < 1000000; i++)
{
result1 += ((rand.Next() % 2 == 0) ? "0" : "1");
}
textBox1.Text = result1.ToString();
答案 0 :(得分:1)
连接字符串是O(N)操作。字符串是不可变的,因此当您添加到字符串中时,新值将被复制到新字符串中,这需要迭代前一个字符串。由于您要为每次迭代添加一个值,因此每次必须读取的数量都会随着每次添加而增加,从而导致性能为O(N ^ 2)。由于您的N是1,000,000,这将花费非常非常长的时间,并且可能正在消耗您存储这些中间丢弃字符串的所有内存。
使用任意数量的输入构建字符串时,通常的解决方案是改用StringBuilder。虽然,一个1,000,000个字符的位字符串仍然是..笨拙的。假设您想要/需要一个位串,则可以将代码更改为以下内容,并提供性能更高的解决方案。
public string GetGiantBitString() {
var sb = new StringBuilder();
var rand = new Random();
for(var i = 0; i < 1_000_000; i++) {
sb.Append(rand.Next() % 2);
}
return sb.ToString();
}
答案 1 :(得分:0)
这对我有用,在我的盒子上大约需要0.035秒:
private static IEnumerable<Byte> MillionBits()
{
var rand = new RNGCryptoServiceProvider();
//a million bits is 125,000 bytes, so
var bytes = new List<byte>(125000);
for (var i = 0; i < 125; ++i)
{
byte[] tempBytes = new byte[1000];
rand.GetBytes(tempBytes);
bytes.AddRange(tempBytes);
}
return bytes;
}
private static string BytesAsString(IEnumerable<Byte> bytes)
{
var buffer = new StringBuilder();
foreach (var byt in bytes)
{
buffer.Append(Convert.ToString(byt, 2).PadLeft(8, '0'));
}
return buffer.ToString();
}
然后:
var myStopWatch = new Stopwatch();
myStopWatch.Start();
var lotsOfBytes = MillionBits();
var bigString = BytesAsString(lotsOfBytes);
var len = bigString.Length;
var elapsed = myStopWatch.Elapsed;
len变量是一百万,字符串看起来像是全1和全0。
如果您真的想填充一个充满零和零的文本框,只需将其Text
属性设置为bigString
。