我发布了一个新的线程,因为上一个是非常混乱的,这个想法也被修改了。我在很多地方改变了程序,没有失去效率(甚至一点点),现在我有了一个简单的整数数组,不需要分隔符。
Previous thread for the reference
我知道这类问题已获多次答覆。虽然我已经找到了许多可能的答案,但它们仍然不能解决我的问题,是实现将整数数组转换为单个字符串的最快方法。
那好吧,
int[] Result = new int[] { 636, 1000234545, 1353678530, 987001 }我应该得到的:
636000234545353678530987001注意,我只取了每个元素的最后9个数字。以下是Honza Brestan的更正版本:
StringBuilder sb = new StringBuilder();
for (var i = 0; i < xC; i++)
{
tempint = Result[i];
if (tempint > 999999999)
sb.Append((Result[i]).ToString().Substring(1, 9));
else
sb.Append((Result[i]).ToString());
}
return sb.ToString();我的,旧的,纠正的:
//Base – a string array of integers saved as strings {“000”, “001”, … , “999” }
string[] arr = new string[3 * limit];
int x; // temp value
for (int i = 0; i < limit; i++)
{
x = Result[i];
if (x > 999999)
{
arr [3 * i + 2] = Base [x % 1000];
arr [3 * i + 1] = Base [x / 1000 % 1000];
arr [3 * i] = Base [x / 1000000 % 1000];
}
else
{
if (x < 1000)
{
arr [3 * i + 2] = Base [x % 1000];
}
else
{
arr [3 * i] = Base [x / 1000 % 1000];
arr [3 * i + 1] = Base [x % 1000];
}
}
}
return string.Join(null, arr);而现在速度的差异: Honza:689 ms My:331 ms
有什么办法提高速度吗?也许用汇编程序?
发布于 2012-11-18 19:38:44
那么并行性呢,也许它对你有帮助?
int[] list = new int[100];
Random rand = new Random();
for(int k = 0; k < list.Length; k++)
{
list[k] = rand.Next(0, 200000);
}
object monitor = new object();
var stopwatch = System.Diagnostics.Stopwatch.StartNew();
char[] result = new char[list.Length * list.Max().ToString().Length];//worst case scenario.
for (int j = 0; j < 120000; j++)
{
//partitioning.
Parallel.ForEach(Partitioner.Create(0, list.Length), () => 0.0, (range, state, local) =>
{
StringBuilder xc = new StringBuilder();
for (int i = range.Item1; i < range.Item2; i++)
{
//split the number into characters.
int number = list[i];
int index = i;
do
{
int lsd = number % 10; // Get least significant // digit
result[index++] = (char)(lsd + 47);
number /= 10; // Prepare for next most // significant digit
} while(number != 0);
}
return 0.0;
}, local => {});
}
stopwatch.Stop(); MessageBox.Show(stopwatch.ElapsedMilliseconds.ToString());为了进行优化,您需要尝试不安全的代码,这将产生更好的性能。C#做了一些安全检查,使事情变得更慢。例如数组索引检查。
分配缓冲区的大小总是正确的,并尽量避免使用string.Join。
发布于 2012-11-19 09:48:01
好的,我相信我解决了我的问题;)只是为了那些想要使用我所做的事情的人。就在我对两个函数进行基准测试之前,这两个函数几乎相同,仅与最后一部分不同,它将整数数组转换为单个字符串。
//Function one:
StringBuilder sb = new StringBuilder();
if (iscarry) sb.Append("1");
xC++;
for (iX = 0; iX < xC; iX++)
{
tempint = Result[iX];
if (tempint > 99999)
{
sb.Append(SmallBase[tempint / 100000 % 10000]);
sb.Append(BigBase[tempint % 100000]);
}
else
{
sb.Append(BigBase[tempint % 100000].TrimStart('0'));
}
}
return sb.ToString();
//Function two:
xC++;
AnswerArr = new string[2 * xC];
for (iX = 0; iX < xC; iX++)
{
tempint = Result[iX];
if (tempint > 99999)
{
AnswerArr[2 * iX] = SmallBase[tempint / 100000 % 10000];
AnswerArr[2 * iX + 1] = BigBase[tempint % 100000];
}
else
{
AnswerArr[2 * iX] = BigBase[tempint % 100000].TrimStart('0');
}
}
return string.Join(null, AnswerArr).TrimStart('0');这两个密码给我的结果是一样的。对于前面的输入,这大约是271ms。
我在想,对于整数数组中的很多元素,StringBuilder会更快一些。所以我写了两个循环,函数应该执行把保存为字符串的整数相加,从2位数到320.000位。结果如下:
with StringBuilder: 5754 ms.
with array & string.Join: 5788 ms.这并不意味着什么,这是可以忽略不计的差别。所以我又做了一次,总共达1.28万位数。
with StringBuilder: 5242 ms.
with array & string.Join: 5248 ms.我可以说,这取决于你选择哪种方式。String Builder更容易理解,占用的空间也更少。第二种处理数组的方法更花哨:D
我想这就是..。希望这能有所帮助。谢谢你的倾听。安息吧!
https://stackoverflow.com/questions/13443011
复制相似问题