请大家帮忙优化下代码!
以前一直是做WEB开发,ASP.NET,最近公司要求做一个能生成5万条互不相同的字符串的功能.
用VS2005创建windows程序,windows程序写好后测试能生成5万条.但是效率很低,花了3分钟时间,CPU使用率在98%-100%之间徘徊.
我的代码如下,想请各位帮忙给优化下,让代码跑起来快些.(初次写windows程序,有很多不懂,希望在CSDN请教各位达人!)
Form1.cs代码:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Text;
namespace createtxt
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
string code = "";
for (int i = 1; i <= 50000; i++)
{
code += rc(i) + "\r\n";
}
label1.Text="已生成五万条随机字符串";
string path = "D:/";
Encoding codee = Encoding.GetEncoding("UTF-8");
StreamWriter sw = new StreamWriter(path + "string.txt", false, codee);
sw.Write(code);
sw.Flush();
sw.Close();
label1.Text = "生成文件成功,文件名为:string.txt";
}
public static string rc(int a)
{
char[] arrchar = new char[]{
'0','1','2','3','4','5','6','7','8','9',
'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z'
};
StringBuilder num = new StringBuilder();
Random rnd = new Random(a);
for (int i = 1; i <= 4; i++)
{
//num2.Append(arrchar[rnd.Next(0,10)].ToString());
//num.Append(arrchar[rnd.Next(0, 10)].ToString());
num.Append(arrchar[rnd.Next(11, arrchar.Length)].ToString());
}
for (int j = 1; j <= 8; j++)
{
num.Append(arrchar[rnd.Next(0, 10)].ToString());
}
return num.ToString();
}
}
}
[解决办法]
在我机器上耗时125毫秒
private const int CODE_COUNT = 50000; // 记录数private byte[] codeBuffer = new byte[14 * CODE_COUNT];private Random random = new Random(); public byte[] RandomCode(){ byte[] vReturn = new byte[14]; vReturn[12] = 13; vReturn[13] = 10; for (int i = 0; i < 4; i++) vReturn[i] = (byte)('A' + random.Next(26)); for (int i = 4; i < 12; i++) vReturn[i] = (byte)('0' + random.Next(10)); return vReturn;}private Hashtable vHashtable = new Hashtable();private void button1_Click(object sender, EventArgs e){ long vTickCount = Environment.TickCount; byte[] code = RandomCode(); for (int i = 0; i < CODE_COUNT; ) { code = RandomCode(); if (!vHashtable.Contains(code)) // 避免重复 { vHashtable.Add(code, null); Array.Copy(code, 0, codeBuffer, i * 14, code.Length); i++; } } FileStream vFileStream = new FileStream(@"c:\temp\temp.txt", FileMode.Create, FileAccess.Write); int vPos = 0; for (; vPos + 0x1000 < codeBuffer.Length; vPos += 0x1000) { vFileStream.Write(codeBuffer, vPos, 0x1000); // 减少文件写入的次数,采用每4096字节写一次。 } vFileStream.Write(codeBuffer, vPos, codeBuffer.Length - vPos); vFileStream.Close(); Console.WriteLine("耗时:{0}毫秒", Environment.TickCount - vTickCount);}
[解决办法]
在zswang代码的基础上,稍微修改了一下:
using System;using System.Collections.Generic;using System.IO;using System.Diagnostics;namespace ConsoleApplication5{ class Program { private const int CODE_COUNT = 50000; // 记录数 private static readonly byte[] NewLine ={ 13, 10 }; private static Random random = new Random(); static void Main(string[] args) { Console.Write("Press Enter to start:"); Console.ReadLine(); Stopwatch sw = Stopwatch.StartNew(); using (FileStream fs = new FileStream("test.txt", FileMode.Create, FileAccess.Write)) using (BinaryWriter bw = new BinaryWriter(fs)) Exec(bw); sw.Stop(); Console.WriteLine("耗时:{0}毫秒", sw.ElapsedMilliseconds); Console.ReadLine(); } public static void RandomCode(ref byte[] buffer) { for (int i = 0; i < 4; i++) buffer[i] = (byte)('A' + random.Next(26)); for (int i = 4; i < 12; i++) buffer[i] = (byte)('0' + random.Next(10)); } private static void Exec(BinaryWriter bw) { Dictionary<int, int> codes = new Dictionary<int, int>(CODE_COUNT); byte[] buffer = new byte[12]; int count = 0; while (count < CODE_COUNT) { RandomCode(ref buffer); int hash = Hash(buffer); if (!codes.ContainsKey(hash)) { codes.Add(hash, 0); bw.Write(buffer); bw.Write(NewLine); count++; } } } private static int Hash(byte[] buffer) { return BitConverter.ToInt32(buffer, 0) ^ BitConverter.ToInt32(buffer, 4) ^ BitConverter.ToInt32(buffer, 8); } }}
[解决办法]
using System.Collections;private const int CODE_COUNT = 50000; // 记录数private Random random = new Random(); public byte[] RandomCode(){ byte[] vReturn = new byte[14]; vReturn[12] = 13; vReturn[13] = 10; for (int i = 0; i < 4; i++) vReturn[i] = (byte)('A' + random.Next(26)); for (int i = 4; i < 12; i++) vReturn[i] = (byte)('0' + random.Next(10)); return vReturn;}private Dictionary<string, int> codeList = new Dictionary<string, int>();private void button1_Click(object sender, EventArgs e){ long vTickCount = Environment.TickCount; codeList.Clear(); byte[] vCode; FileStream vFileStream = new FileStream(@"c:\temp\temp.txt",FileMode.Create, FileAccess.Write); for (int i = 0; i < CODE_COUNT; ) { vCode = RandomCode(); string S = BitConverter.ToString(vCode); if (!codeList.ContainsKey(S)) // 避免重复 { codeList.Add(S, i);i++; vFileStream.Write(codeBuffer, 0, codeBuffer.Length); //这样更快,因为本身有循环 } } vFileStream.Close(); Console.WriteLine("耗时:{0}毫秒", Environment.TickCount - vTickCount);}