将大文本分割成小块的最快方法

2024-02-09

我使用下面的代码来分割字符串,但这需要很多时间。

using (StreamReader srSegmentData = new StreamReader(fileNamePath))
{
    string strSegmentData = "";
    string line = srSegmentData.ReadToEnd();
    int startPos = 0;

    ArrayList alSegments = new ArrayList();
    while (startPos < line.Length && (line.Length - startPos) >= segmentSize)
    {
        strSegmentData = strSegmentData + line.Substring(startPos, segmentSize) + Environment.NewLine;
        alSegments.Add(line.Substring(startPos, segmentSize) + Environment.NewLine);
        startPos = startPos + segmentSize;
    }
}

请建议我一种将字符串分割成固定大小的较小块的替代方法


首先你应该定义你的意思块大小。如果你的意思是具有固定数量的块代码单元那么你的实际算法可能很慢但它有效。如果这不是你的意图和你真正的意思具有固定数量的块人物然后它就坏了。我在这篇代码审查帖子中讨论了类似的问题:将字符串分割成相同长度的块 https://codereview.stackexchange.com/q/111919/13424那么我在这里只重复相关部分。

  • 你正在分区Char but String是 UTF-16 编码那么你可以生成broken字符串至少存在三种情况:

    1. 一个字符由多个代码单元编码。该字符的 Unicode 代码点被编码为两个 UTF-16 代码单元,每个代码单元可能最终出现在两个不同的切片中(并且两个字符串都将invalid).
    2. 一个字符由多个码位组成。您正在处理由两个单独的 Unicode 代码点组成的字符(例如汉字 ????)。
    3. One character has combining characters or modifiers. This is more common than you may think: for example Unicode combining character like U+0300 COMBINING GRAVE ACCENT used to build à and Unicode modifiers such as U+02BC MODIFIER LETTER APOSTROPHE.
  • 的定义特点对于编程语言和人类来说是非常不同的,例如在斯洛伐克语中是单个字符,但它是由 2/3 Unicode 代码点组成,在本例中也是 2/3 UTF-16 代码单元"dž".Length > 1。有关此内容和其他内容的更多信息文化问题 on 如何执行 Unicode 感知的逐个字符比较? https://stackoverflow.com/a/27229590/1207195.
  • 连字存在。假设一个连字是一个代码点(并且还假设它被编码为一个代码单元),那么您将把它视为一个单一的glyph然而它代表了两个人物。这种情况该怎么办?一般定义特点可能很模糊,因为它有不同的meaning根据使用该词的纪律。您(可能)无法正确处理所有事情,但您应该设置一些约束并记录代码行为。

一种提议的(且未经测试的)实现可能是这样的:

public static IEnumerable<string> Split(this string value, int desiredLength)
{
    var characters = StringInfo.GetTextElementEnumerator(value);
    while (characters.MoveNext())
        yield return String.Concat(Take(characters, desiredLength));
}

private static IEnumerable<string> Take(TextElementEnumerator enumerator, int count)
{
    for (int i = 0; i < count; ++i)
    {
        yield return (string)enumerator.Current;

        if (!enumerator.MoveNext())
            yield break;
    }
}

它没有针对速度进行优化(正如您所看到的,我尝试使用枚举来保持代码简短明了),但是对于大文件,它的性能仍然比您的实现更好(原因请参阅下一段)。

关于您的代码请注意:

  • 你正在建造一个巨大的ArrayList(?!) 保存结果。另请注意,通过这种方式您可以调整大小ArrayList多次(即使给定输入大小和块大小,然后其最终大小已知)。
  • strSegmentData被重建多次,如果需要积累字符则必须使用StringBuilder否则每个操作都会分配一个新字符串并复制旧值(这很慢并且还会增加垃圾收集器的压力)。

有更快的实现(请参阅链接的代码审查帖子,特别是Heslacher 的实现 https://codereview.stackexchange.com/a/112018/13424以获得更快的版本)并且如果您不需要正确处理 Unicode(您是sure你只管理 US ASCII 字符)那么还有一个漂亮的Jon Skeet 的可读实现 https://stackoverflow.com/a/1632109/1207195(请注意,在对代码进行分析后,您仍然可以通过预分配正确大小的输出列表来提高大文件的性能)。我不会在这里重复他们的代码,请参阅链接的帖子。

在你的具体您不需要读取内存中的整个大文件,你可以读取/解析n一次字符(不必太担心磁盘访问,I/O 已缓冲)。它会稍微降低性能,但会大大提高内存使用率。或者,您可以逐行读取(设法处理跨行块)。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

将大文本分割成小块的最快方法 的相关文章

  • std::list 线程push_back、front、pop_front

    std list 线程安全吗 我假设不是这样 所以我添加了自己的同步机制 我认为我有正确的术语 但我仍然遇到问题 每个函数都由单独的线程调用 Thread1 不能等待 它必须尽可能快 std list
  • C++11 删除重写方法

    Preface 这是一个关于最佳实践的问题 涉及 C 11 中引入的删除运算符的新含义 当应用于覆盖继承父类的虚拟方法的子类时 背景 根据标准 引用的第一个用例是明确禁止调用某些类型的函数 否则转换将是隐式的 例如最新版本第 8 4 3 节
  • 如何在 C# 中打开 Internet Explorer 属性窗口

    我正在开发一个 Windows 应用程序 我必须向用户提供一种通过打开 IE 设置窗口来更改代理设置的方法 Google Chrome 使用相同的方法 当您尝试更改 Chrome 中的代理设置时 它将打开 Internet Explorer
  • free 和 malloc 在 C 中如何工作?

    我试图弄清楚如果我尝试 从中间 释放指针会发生什么 例如 看下面的代码 char ptr char malloc 10 sizeof char for char i 0 i lt 10 i ptr i i 10 ptr ptr ptr pt
  • -webkit-box-shadow 与 QtWebKit 模糊?

    当时有什么方法可以实现 webkit box shadow 的工作模糊吗 看完这篇评论错误报告 https bugs webkit org show bug cgi id 23291 我认识到这仍然是一个问题 尽管错误报告被标记为RESOL
  • 用于 FTP 的文件系统观察器

    我怎样才能实现FileSystemWatcherFTP 位置 在 C 中 这个想法是 每当 FTP 位置添加任何内容时 我都希望将其复制到我的本地计算机 任何想法都会有所帮助 这是我之前问题的后续使用 NET 进行选择性 FTP 下载 ht
  • 需要帮助优化算法 - 两百万以下所有素数的总和

    我正在尝试做一个欧拉计划 http projecteuler net问题 我正在寻找 2 000 000 以下所有素数的总和 这就是我所拥有的 int main int argc char argv unsigned long int su
  • 访问外部窗口句柄

    我当前正在处理的程序有问题 这是由于 vista Windows 7 中增强的安全性引起的 特别是 UIPI 它阻止完整性级别较低的窗口与较高完整性级别的窗口 对话 就我而言 我想告诉具有高完整性级别的窗口进入我们的应用程序 它在 XP 或
  • x:将 ViewModel 方法绑定到 DataTemplate 内的事件

    我基本上问同样的问题这个人 https stackoverflow com questions 10752448 binding to viewmodels property from a template 但在较新的背景下x Bind V
  • C# xml序列化必填字段

    我需要将一些字段标记为需要写入 XML 文件 但没有成功 我有一个包含约 30 个属性的配置类 这就是为什么我不能像这样封装所有属性 public string SomeProp get return someProp set if som
  • C 编程:带有数组的函数

    我正在尝试编写一个函数 该函数查找行为 4 列为 4 的二维数组中的最大值 其中二维数组填充有用户输入 我知道我的主要错误是函数中的数组 但我不确定它是什么 如果有人能够找到我出错的地方而不是编写新代码 我将不胜感激 除非我刚去南方 我的尝
  • 空指针与 int 等价

    Bjarne 在 C 编程语言 中写道 空指针与整数零不同 但 0 可以用作空指针的指针初始值设定项 这是否意味着 void voidPointer 0 int zero 0 int castPointer reinterpret cast
  • 为什么 isnormal() 说一个值是正常的,而实际上不是?

    include
  • 如何在 Linq to SQL 中使用distinct 和 group by

    我正在尝试将以下 sql 转换为 Linq 2 SQL select groupId count distinct userId from processroundissueinstance group by groupId 这是我的代码
  • C 函数 time() 如何处理秒的小数部分?

    The time 函数将返回自 1970 年以来的秒数 我想知道它如何对返回的秒数进行舍入 例如 对于100 4s 它会返回100还是101 有明确的定义吗 ISO C标准没有说太多 它只说time 回报 该实现对当前日历时间的最佳近似 结
  • 编译时展开 for 循环内的模板参数?

    维基百科 here http en wikipedia org wiki Template metaprogramming Compile time code optimization 给出了 for 循环的编译时展开 我想知道我们是否可以
  • 使用特定参数从 SQL 数据库填充组合框

    我在使用参数从 sql server 获取特定值时遇到问题 任何人都可以解释一下为什么它在 winfom 上工作但在 wpf 上不起作用以及我如何修复它 我的代码 private void UpdateItems COMBOBOX1 Ite
  • 为什么C++代码执行速度比java慢?

    我最近用 Java 编写了一个计算密集型算法 然后将其翻译为 C 令我惊讶的是 C 的执行速度要慢得多 我现在已经编写了一个更短的 Java 测试程序和一个相应的 C 程序 见下文 我的原始代码具有大量数组访问功能 测试代码也是如此 C 的
  • 在OpenGL中,我可以在坐标(5, 5)处精确地绘制一个像素吗?

    我所说的 5 5 正是指第五行第五列 我发现使用屏幕坐标来绘制东西非常困难 OpenGL 中的所有坐标都是相对的 通常范围从 1 0 到 1 0 为什么阻止程序员使用屏幕坐标 窗口坐标如此严重 最简单的方法可能是通过以下方式设置投影以匹配渲
  • 类型或命名空间“MyNamespace”不存在等

    我有通常的类型或命名空间名称不存在错误 除了我引用了程序集 using 语句没有显示为不正确 并且我引用的类是公共的 事实上 我在不同的解决方案中引用并使用相同的程序集来执行相同的操作 并且效果很好 顺便说一句 这是VS2010 有人有什么

随机推荐