【问题标题】:How to overcome hardware limitations when reading/writing to a file.如何在读取/写入文件时克服硬件限制。
【发布时间】:2013-02-17 15:42:47
【问题描述】:

我最近在一次采访中被问到这个问题。

给定一个输入文件、一个正则表达式和一个输出文件。读取输入文件,将每一行与正则表达式匹配,并将匹配的行写入输出文件。

我想出了使用链接到 FileReader 的 BufferedReader 的粗略方案(以优化从磁盘读取)。我使用了类似的写作方案。

然后面试官说这个过程需要 3 秒从文件中读取一行,1 秒将正则表达式与该行进行比较,另外 5 秒写回。所以每行总共需要9秒。我们该怎样改进这个?

我建议一次读取整个文件,处理它并立即写入整个输出文件。但是,有人告诉我这无济于事(写 1 行 = 5 秒,写 2 行 = 10 秒)。

面试官进一步表示,这是由于硬件/硬盘驱动器的限制。有人问我如何改进我的代码以减少每行的总秒数(当前为 9 )?

我只能想到缓冲读/写,也找不到太多关于 SO 的内容。有什么想法吗 ?

【问题讨论】:

  • 多线程和同步?您不必等待 1 秒进行正则表达式处理并继续阅读下一行。正则表达式处理结束后,另一个线程正在等待匹配的行可以写入输出。但我怀疑这最后一步会带来很大的改进,因为你有一张光盘,它可以读取或写入一个特定的时刻。

标签: java file file-io filestream bufferedreader


【解决方案1】:

我认为面试官正在寻找一种在写入输出的同时执行读取/正则表达式检查的解决方案。如果您设置一个通过读取和过滤异步填充的工作队列,并将写入放在一个单独的线程中,那么从第二行开始,合并的过程每行需要 5 秒。

这里的假设是读取、解析和写入可以相互独立地发生。在这种情况下,您可以在编写第 1 行的同时阅读第 2 行:您只需要四秒钟来读取和应用您的正则表达式,并且在编写器准备好第二行之前您有整整五秒钟的时间。写作仍然是你的瓶颈,但整个过程加快了大约 44%,这还不错。

【讨论】:

    【解决方案2】:

    既然读取时间是固定的,写入时间是固定的,那么在这种情况下,您唯一的选择就是更改正则表达式位的性质。

    您可以编写代码来快速应用 regex 测试,而无需 regex 可以做的所有聪明事情的开销。

    另一方面,如果问题是每个 IO 请求需要几秒钟才能执行,但限制不是实际驱动器,那么让多个读取器同时读取。

    【讨论】:

      【解决方案3】:

      棘手的问题,因为我们对系统了解不多。

      我的猜测是使用线程/异步处理。使用一个 Thread 读取,一个处理两个或多个进行写入,从而减少 IO Wait 所花费的时间。

      让我尝试将其转换为 ASCII 图表:

      • R/r 表示读取(3 秒)
      • P/p 表示处理(1 秒)
      • W/w 表示写作(5 秒)

      大写字母标记开始,小写字母标记继续工作。 “:”表示线程空闲

      Thread 1: RrrRrrRrrRrrRr
      Thread 2: ...P..P..P..P.
      Thread 3: ....Wwwww
      Thread 4: .......Wwwww
      

      使用此设置,第一批在 9 秒后被写回(这里没什么可做的),但第二批在 12 秒后完成。单线程第二个总共需要 18 秒

      【讨论】:

        猜你喜欢
        • 2019-11-22
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-10-11
        • 1970-01-01
        • 2019-11-13
        相关资源
        最近更新 更多