0

假设我正在逐行读取一个文件(包含 8 亿行),然后处理数据(非常轻量级的处理,基本上是格式化字符串),然后将处理后的行写入另一个文件。

如果我想为从文件中读取的每 100 万行打印一个语句,一个基本的方法是添加一个 if 语句检查迭代变量,并且对于每个 %million == 0,我打印该语句。

现在,这段代码在每次迭代中检查索引是否达到下一个百万,这是每次迭代中的额外处理,对吗?

有没有其他有效的方法可以做到这一点,只有当迭代索引变量达到百万倍时,才会发送一些信号并打印语句?

4

4 回答 4

3

现在,这段代码在每次迭代中检查索引是否达到下一个百万,这是每次迭代中的额外处理,对吗?

正确的

有没有其他有效的方法可以做到这一点,只有当迭代索引变量达到百万倍时,才会发送一些信号并打印语句?

不,没有1

但不要担心这是“低效的”。测试的成本很可能比读取和处理数据的成本低2 个或更多数量级。

1 - 经过反思,在某些情况下,减少专用计数器并测试它是否为零可能更有效。此外,如果计数器溢出,'%' 方法将无法正常工作。


一般建议。不要花时间在这个级别上“优化”事情,除非你有证据表明你有瓶颈。您需要使用真实数据来分析您的应用程序,以便您可以决定是否值得优化应用程序的这一方面。

于 2013-03-21T12:29:34.563 回答
3

在我的机器上,以下需要 1.4 秒:

    for (int i = 0; i < 800000000; ++i) {
        if (i % 1000000 == 0) {
            System.out.print('.');
        }
    }

这表明你会没事的。但是,如果有疑问,请提供个人资料。

于 2013-03-21T12:29:52.630 回答
1

如果你想要一个线性解决方案,就像Stephen C所说的那样,这是不可能的最佳方式,

但是当我们谈论并行性时,有一个最佳解决方案,

例如,如果您的迭代进程状态可以被另一个正在另一个处理器上工作的线程访问,那么它可以在给定时间点告诉您它的状态,而不会中断您的迭代进程,

这也是最佳的,因为打印状态会花费您的迭代过程Θ(0),因为它是由外部线程在并行处理流\处理器上完成的

希望这可以帮助

于 2013-03-21T14:21:59.407 回答
0

您有 800M 行文本数据,需要处理然后复制到单个 TextFile

  • 我更喜欢公共参数“NotifyAfter”,在你的情况下是 1M 。
  • 然后,如果需要,我可以将 800M 行拆分为一批 {NotifyAfter} 并将它们存储在数组或队列中 {Start,End} 。
  • 现在我可以产生一些线程,我必须小心这里的 Race/Deadlock,因为它们都是从同一个文件中读取的。
  • 然后每个子流程将完成它的工作并引发一个事件 - TaskComplete(增加已处理的行数)
    • 在这里,您必须决定 - 您的线程是否将所有内容写入较小的文件,然后将它们拼接在一起
    • 或者您可以同步代码以写入同一个文件。

我同意斯蒂芬-不要优化,除非有瓶颈的证据

希望这可以帮助 !!

于 2013-03-21T13:17:42.653 回答