【问题标题】:Load a single file at a time or all files at once into dictionary一次加载单个文件或一次将所有文件加载到字典中
【发布时间】:2016-03-02 15:43:08
【问题描述】:

我一直在做一些工作,将多个图像文件加载到 HTML 文档中,然后将其转换为 PDF。

我不确定具体细节,但我的印象是一次读取一个文件并保持较低的内存占用,而不是一次将所有文件加载到内存(在字典中)(那里有这么多图像 - 集合可以大到 500MB!)。

我想知道什么更快?将 100MB 的文件读入内存,处理它们,然后再加载 100MB 会更快吗?还是一次处理一个文件更好(当然磁盘 I/O 操作的数量在这两个方面都相似)?

【问题讨论】:

  • 当主要操作如此昂贵时,您不太可能注意到差异。内存快,I/O 慢。你应该更专注于创建一个在这些图像占用千兆字节时仍然可以工作的程序。这并非不可能。
  • 是的,数字。我知道 IO 操作会很慢,但没有其他办法!

标签: c# image dictionary memory loading


【解决方案1】:

最好一个一个地读取文件,因为它更节省内存。如果可以的话,你应该只使用流而不是内存缓冲区。

当您使用更多内存时,您的数据可能以page file 结尾,从而导致更多磁盘 I/O 操作。

如果您不想看到OutOfMemoryException,则应避免使用大内存块。

【讨论】:

  • 同意,我一直在 MemoryStream 阵营进行这部分的开发。仅将图像作为流加载,还是将其加载到位图/图像中并在那里工作会更好吗?我猜直接直播会更好
  • MemoryStream 是内存缓冲区的包装器,而不是“真正的”流。如果可以,不要加载图像,使用原始数据(FileStream 或类似的东西)
【解决方案2】:

这取决于很多因素,但从根本上说,磁盘比内存慢很多,所以如果你做对了,你可以通过阅读获得收益。

首先,警告:如果您没有足够的内存来容纳您尝试加载的文件,那么您的操作系统会将内存分页到磁盘,这将大大降低您的系统速度,而不是一次读取一个文件,所以要小心。

提高磁盘 io 性能的关键是保持磁盘繁忙。当您在内存中处理文件时,一次读取一个会使磁盘空闲。将一组文件读入一大块内存,但仍一次读取一个,然后处理该文件块,除非在非常不寻常的情况下,否则可能不会提高性能。

如果您的目标是减少从开始到结束处理这些文件的时间,您可能希望在多个线程上运行;打开和读取文件的系统调用仍然需要时间来排队,因此根据磁盘的能力,您通常可以通过在磁盘加载另一个请求时将至少一个读取请求排队来获得更好的整体 io 吞吐量;这最大限度地减少了请求之间的空闲时间,并使磁盘保持在其绝对最大值。请注意,排队的请求过多会降低性能。

由于内存中的处理可能更快,您可以设置至少 2 个线程来读取文件,并设置至少 1 个线程来处理已被其他线程加载到内存中的文件。

比管理自己的线程更好的方法是使用线程池;这自然会将 io 请求的数量限制为允许的并发线程数,并且不需要您自己管理线程。这可能不是很理想,但线程池应该比一次处理一个文件更快,并且比管理线程更容易/更安全。

请注意,如果您不理解我所说的线程和线程池的含义,或者您没有做过很多与磁盘 io 相关的多线程开发,那么您最好一次只使用一个文件,除非提高总处理时间是您无法解决的要求。 MSDN 上有很多关于如何使用线程的示例,但如果你没有做太多,这可能不是一个很好的第一个线程项目。

【讨论】:

    猜你喜欢
    • 2011-04-15
    • 1970-01-01
    • 2010-09-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-06-28
    • 1970-01-01
    相关资源
    最近更新 更多