0

我发布了一个新线程,因为上一个线程非常混乱,并且这个想法也被修改了。我在很多地方更改了程序,没有损失效率(甚至获得一点),现在我有一个简单的整数数组,就像以前一样,不需要分隔符。

上一个线程供参考

我知道这类问题已经回答过很多次了。尽管我找到了很多可能的答案,但它们仍然没有解决我的问题,即实现将整数数组转换为单个字符串的最快方法

那好吧,

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 我的:331 ms

任何想法如何提高速度?也许使用汇编程序?

4

2 回答 2

0

Parallelism怎么样,也许它对你有帮助?

    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-18T19:38:44.407 回答
0

好的,我相信我解决了我的问题;)只是为了其他想使用我所做的事情的人。就在我对两个函数进行基准测试之前,几乎相同,仅在最后一部分不同,将整数数组转换为单个字符串。

//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');

两个代码都给了我相同的结果。这大约是前一个输入的271 毫秒

我在想对于整数数组的很多元素,StringBuilder 会快一点。所以我写了两个循环,函数应该执行保存为字符串的整数相加,一起从 2 位数字到 320.000。结果如下:

with StringBuilder: 5754 ms.
with array & string.Join: 5788 ms.

没有任何意义,这是一个微不足道的区别。所以我又做了一次,总共有 1.280.000 位数字。

with StringBuilder: 5242 ms.
with array & string.Join: 5248 ms.

我可以说,这取决于你选择哪种方式。String Builder 更容易理解并且占用更少的空间。数组的第二种方式更花哨:D

我想这就是全部......希望这会有所帮助。谢谢收听。和平!

于 2012-11-19T09:48:01.083 回答