【问题标题】:How to check if a char is valid in C++如何检查一个char在C++中是否有效
【发布时间】:2013-06-03 04:59:11
【问题描述】:

我需要一个程序来读取文件的内容并将它们写入另一个文件,但只有有效的 utf-8 字符。问题是文件可能采用任何编码,文件的内容可能对应也可能不对应这种编码。

我知道这是一团糟,但这就是我要处理的数据。我需要“清理”的文件可能高达几 TB,因此我需要程序尽可能高效。目前我正在使用我用 python 编写的程序,但清理 100gb 需要长达一周的时间。

我正在考虑使用 w_char 函数读取字符,然后将它们作为整数进行管理,并丢弃所有不在某个范围内的数字。这是最优解吗?

还有什么是最有效的 C/C++ 读写方式?

编辑: 问题不在于 IO 操作,这部分问题旨在为更快的程序提供额外帮助,但真正的问题是如何快速识别非 UTF 字符。另外,我已经尝试过腭化和 RAM 磁盘。

【问题讨论】:

  • 一周???喂那些老鼠,让轮子转得更快!
  • 你说问题不在于IO,但需要一周? Cpu 真的一直在使用 100% 的核心吗?如果是,那么也许显示关键的来源。在 C/C++ 中使用 fread() 等的程序会很快做到这一点,这就是为什么每个人都会自然而然地认为 IO 问题。还是您更想问如何用 C++ 编写整个事情?
  • @rlb 问题应该是关于如何有效地丢弃无效的 utf8 字符(CPU 几乎在完成它所需的整个一周内达到 100%)。 IO 性能只是为了让它更快(我有时间,而且这个软件会被大量使用,所以很少的性能调整等于几天获得)。我分析了我的 python 代码,问题在于所有的字符串处理函数和编码/解码函数。这就是为什么我问将它们作为整数管理是否是正确的方法(我也非常感谢其他建议)。

标签: c++ optimization utf


【解决方案1】:

Utf8 只是一种很好的字符编码方式,并且具有非常明确的结构定义,因此从根本上来说,读取一块内存并验证它是否包含 utf8 是相当简单的。大多数情况下,这包括验证某些位模式不会出现,例如 C0、C1、F5 到 FF。 (取决于位置)

在 C 语言中(对不起,不会说 python)编写简单的 fopen/fread 并检查每个字节的位模式是相当简单的,尽管我建议找到一些代码来剪切/粘贴(例如 @987654321 @ 但我没有使用这些确切的例程),因为有一些警告和特殊情况需要处理。只需将输入字节视为无符号字符并直接对它们进行位掩码。我会粘贴我使用的东西,但不是在办公室。

C 程序将很快成为 IO 受限的,因此如果您想要获得最终性能,那么有关 IO 的建议将适用,但是如果您做得对,像这样的直接字节检查将很难在性能上被击败。 Utf8 很好,即使从文件中间开始也可以找到边界,因此这很好地导致了并行算法。

如果您自己构建,请注意可能出现在某些文件开头的 BOM 掩码。

链接

http://en.wikipedia.org/wiki/UTF-8 清晰的概览,表格显示有效位模式。

https://www.rfc-editor.org/rfc/rfc3629 描述 utf8 的 rfc

http://www.unicode.org/ unicode 联盟主页。

【讨论】:

    【解决方案2】:

    在我看来,你最好的选择是并行化。如果您可以并行清理并同时清理许多内容,那么该过程将更有效率。我会研究一个并行化框架,例如mapreduce,您可以在其中对任务进行多线程处理。

    【讨论】:

    • 目前我所做的是将一个非常大的文件分成更小的(100gb)文件并同时清理每个文件。但是在对程序进行分析之后,比较慢的部分是python的字符串管理功能,所以我认为更高效的程序和更高效的解决方案是有序的。
    【解决方案3】:

    我会查看内存映射文件。这是微软世界里的东西,不确定它是否存在于 unix 等,但可能会。

    基本上,您打开文件并将操作系统指向它,然后它将文件(或其中的一部分)加载到内存中,然后您可以使用指针数组访问该内存。对于 100 GB 的文件,您一次可以加载大约 1GB,处理然后写入内存映射的输出文件。

    http://msdn.microsoft.com/en-us/library/windows/desktop/aa366556(v=vs.85).aspx

    http://msdn.microsoft.com/en-us/library/windows/desktop/aa366542(v=vs.85).aspx

    我认为这应该是执行大 I/O 的最快方法,但您需要测试才能确定。

    HTH,祝你好运!

    【讨论】:

    • 谢谢。我试过了。我使用gb RAM驱动优化IO,但问题不在于IO操作,而在于代码的“清理”部分。
    • 使用较低级别的语言(例如 C/C++)可能会获得更好的吞吐量。大概python有一些开销。除了编写翻译逻辑然后测试/调整/测试直到获得满意的性能,我认为这里没有任何简单的解决方案
    【解决方案4】:

    Unix/Linux 和任何其他 POSIX 兼容的操作系统都支持内存映射 (mmap)。

    【讨论】:

    • 谢谢,但与@Chris Leckie 给出的答案相同。我试过了。我使用gb RAM驱动器来优化IO,但问题不在于IO操作,而在于代码的“清理”部分。我可以在几分钟内将一个 100gb 的文件转换为其他文件。问题是 python 字符串管理。
    猜你喜欢
    • 2010-10-29
    • 2016-05-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-01-20
    • 1970-01-01
    • 2012-03-15
    • 2021-10-12
    相关资源
    最近更新 更多