【问题标题】:stackalloc (C# Reference)stackalloc(C# 参考)
【发布时间】:2016-03-08 10:17:25
【问题描述】:

我正在尝试解析 130,000 个文档,并且我正在尝试尽可能快地做到这一点。

此函数用于删除文档中的分隔符。

public static unsafe string StripRestAndNewlines(string s)
{
    int len = s.Length;
    char* newChars = stackalloc char[len];
    char* currentChar = newChars;

    for (int i = 0; i < len; ++i)
    {
        char c = s[i];
        switch (c)
        {
            case ',':
            case '.':
            case ':':
            case ';':
            case '-':
            case '>':
            case '<':
            case '/':
            case '\\':
            case '?':
            case '"':
            case '*':
            case '&':
            case '_':
            case '+':
            case '@':
            case '[':
            case ']':
            case '!':
            case '=':
            case '%':
            case '#':
                continue;
            default:
                *currentChar++ = c;
                break;
        }
    }
  return new string(newChars, 0, (int)(currentChar - newChars));            
}

但在运行程序 2 分钟后停止,我得到了

system.StackOverflowException

是否有任何 delete[] 的 free 用于分配?

谢谢!

【问题讨论】:

  • 为什么你要为此使用堆栈分配?大概您的文档非常大...尝试分配堆栈上字符串所需的全部内存对我来说似乎是个坏主意。
  • 我正在尝试使用尽可能少的内存,这也是我找到的最快的方法。这就是为什么我正在寻找一种方法来释放/删除分配。
  • 如果您尝试删除字符,我想知道您不会编写自己的小扩展方法来替换特定字符public static string ReplaceCharsAt(this string input, int index, char newChar)
  • 通常使用更少的内存与尽可能快的速度相反。
  • 嗯,你仍然在它的末尾创建一个新字符串 - 所以你可以克隆原始字符串,然后修改它的固定版本。

标签: c# memory information-retrieval text-parsing


【解决方案1】:

我认为没有删除方法。它是一个堆栈,您可以在顶部添加一些内容,并从顶部删除一些内容。您不能从堆栈中间删除东西。当方法返回时,分配的内存会自动释放。 我认为当传入的字符串很长时会发生 stackoverflow。使用堆内存来完成此任务。只需创建一个新数组即可。

【讨论】:

  • 仍然堆让我变慢,但很高兴知道我不能感谢。
  • 那么也许创建一个静态数组?您将避免每次方法调用都创建实例。如果传入的字符串太大,您将调整该数组的大小。
【解决方案2】:

是否有任何 delete[] 的 free 用于分配?

是的,什么都不做。由于它是堆栈分配的,它会在方法返回后立即被删除(你提到的delete[] 表明你正在类比 C++,但请注意,在 C++ 中你没有 delete[] 堆栈分配的变量)。

但你不会走那么远,因为你分配了太多的堆栈。

stackalloc 的用途非常有限。它往往比仅使用堆内存要慢,除非您将其用作fixed 的替代品,或者在不同线程允许同时分配大型数组的少数情况下。它只适合在外面使用小于几千字节的数组。

使用堆数组会更好。使用指针和fixed 可能会更好,也可能不会更好。

将文档分块解析会好得多。如果可能的话,仅将它们从流中加载到 4kiB 或 8kiB 的中等大小的段中,并在每个这样的块出现时对其进行处理。

【讨论】:

    猜你喜欢
    • 2011-05-14
    • 2023-04-01
    • 1970-01-01
    • 2010-11-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-27
    • 1970-01-01
    相关资源
    最近更新 更多