【问题标题】:How to impove speed of the algorithm如何提高算法的速度
【发布时间】:2021-08-14 16:27:01
【问题描述】:

我在每次迭代时都有这个方法,字符串的奇数字符被组合并包裹到它的开头,偶数字符被包裹到结尾。 source 是源字符串。 count 是迭代次数。

        public static string Shuffle(string source, int count)
        {
        for (long i = 0; i < count; i++)
        {
            source = string.Join(string.Empty, source.Where((v, j) => j % 2 == 0))
            + string.Join(string.Empty, source.Where((v, j) => j % 2 != 0));
        }

        return source;
        }

一切正常,但当count = int.MaxValue 计算时间过长时。如何更改算法以加快计算速度?

【问题讨论】:

  • 你制造了很多垃圾。字符串是不可变的。我会选择一个数组。
  • 使用StringBuilder 可能会更快(我怀疑您正在分离出太多垃圾,GC 会减慢您的速度)。但是没有什么比string.Join 更方便的了(尽管可能想写一些类似的东西)。如果您可以预先计算出您的结果有多大,请使用具有容量的构造函数。
  • 我的立场是正确的。你说得对,它在 20 亿次迭代中很慢(我在 5 分钟后放弃了)。对于少量迭代,使用StringBuilder 更快。但是... 2000 万,您的代码需要将近一分钟。虽然使用预分配的 StringBuilder 需要大约 2.5 倍的时间,然后在调用 StringBuilder.ToString 时抛出内存不足异常(这很奇怪,这是一个 AnyCPU 构建(没有 Prefer 32 bit)。我很好奇你为什么要这样做

标签: c# .net optimization


【解决方案1】:

字符串是不可变的,您可以通过使用字符数组来避免在循环内创建它们(以 C 方式进行)。 Shuffle2("ABCDEFGHIKKLMNOP", int.MaxValue) 耗时 67 秒。但这是一种能源浪费,该算法是周期性的,周期性长度为长度(文本)(在偶数字符串长度)。 Shuffle("ABCD", x) 将给出与 Shuffle("ABCD", x+4) 相同的结果

public static string Shuffle2(string source, int count)
{
    char[] text = source.ToCharArray();
    char[] buffer = new char[source.Length];

    for (long i = 0; i < count; i++)
    {
        int j = 0;
        for (int k = 0; k < text.Length; k += 2, j++) buffer[j] = text[k];  // Odd characters at index 0, 2, 4, ...
        for (int k = 1; k < text.Length; k += 2, j++) buffer[j] = text[k];  // Place even characters after the odd characters in the buffer.
        buffer.CopyTo(text, 0);  // Maybe there is a tricky exchange in your original array where you don't need a buffer.
    }

    return new string(text);
}

【讨论】:

    猜你喜欢
    • 2021-12-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-12-20
    • 2018-08-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多