进程或线程是最好的,更快的,占用更少的内存
本文关键字:内存 线程 进程 | 更新日期: 2023-09-27 18:27:57
我有20个文本文件存储在硬盘中,每个文件包含数百万个关于教育机构的信息。假设我有一个方法,它将循环迭代文本文件并处理.这是为每个文本文件(Factory.startnew(((启动每个线程或为每个文本文件(process.start(((启动每个进程的最佳方法
编辑我有8GB RAM,8核服务器,所以想到在线程或进程中处理它们。目前我正在使用流程,到目前为止我没有发现任何瓶颈。但是我在使用线程或进程方面陷入了困境
硬盘的读取速度很可能是这里的瓶颈。
因此,根据您需要对数据进行的处理,使用多个线程可能会也可能不会有趣(我当然不会使用进程(。
然而,最重要的是确保没有多个线程同时访问同一个物理磁盘,因为这会导致速度变慢,因为不断切换和寻找硬盘磁头。
我最近对此进行了一些测试,在某些情况下(取决于 hdd 和/或 PC(,操作系统会处理它,它没有太大区别,但是在另一种组合中,可以看到速度减慢到正常速度的 1/10。
因此,如果使用多个线程(仅当数据处理时间超过从硬盘读取的时间时才需要!(,请确保在某处有锁,以防止多个线程同时从磁盘读取。
您可能还想为此查看内存映射文件。
编辑:
如果您正在使用缓冲区,则可以启动一个线程来连续填充缓冲区,而另一个线程处理数据。
edit2(回答米奇(:
"进程或线程哪个最好,更快,占用更少的内存?">
正如我所说,我不将使用进程(由于额外的开销(。这留下了线程,或者根本没有线程 - 取决于需要对数据完成的处理量。如果直接从内存缓冲区读取数据(而不是使用类似readline
的东西,例如,所有投注都将关闭(,则一个或最多两个线程可能是最佳选择(如果数据处理足够快 - 需要测试和计时以确保(。
至于速度和内存使用:最好的选择(对我来说(是内存映射文件(文件以仅向前模式打开(。这不仅会利用操作系统磁盘缓存的效率,而且还会直接访问内核内存 - 而当使用(用户(缓冲区时,内存必须从内核复制到用户空间,这需要时间并使用额外的内存。
IOCP:好的,但取决于线程会问什么。例如,如果 10 个线程每次轮流请求 100kB(在不同的文件上(,则需要 10 x 10ms 的寻道时间,而读取 100Kb 将需要不到 1 毫秒的时间。未来请求的寻道时间将取决于 IOCP 如何处理缓存,这可能与使用内存映射相同,但我认为在这种情况下 IOCP 不会更快。
使用 IOCP,可能还会在用户空间中复制/填充缓冲区(并且通常可能更难处理(。但我不得不说,在写我的答案时,我在想 C/C++(使用直接访问内存缓冲区(,后来才看到它是 C#。尽管原则保持不变,但也许 C# 中有一种简单的方法可以将异步 I/O 与 IOCP 一起使用。
至于速度测试和同时避免读取:我已经在大文件上用 50 多个线程(通过内存映射(进行了测试 - 如果操作正确,不会损失读取速度。另一方面,当只是触发一些线程并让它们随机访问硬盘时(即使是在大块中(,在某些情况下,总读取速度可能会降低到 10% - 有时甚至根本不会。相同的PC,其他硬盘,其他结果。