C# 进程或线程哪个最好、更快、占用更少内存?

C# 进程或线程哪个最好、更快、占用更少内存?,c#,.net,task-parallel-library,C#,.net,Task Parallel Library,我有20个文本文件存储在硬盘中,每个文件包含数百万关于教育组织的信息。假设我有一种方法,可以在循环和进程中迭代文本文件。对于每个文本文件(Factory.startnew())或每个文本文件(process.start())启动每个线程,哪种方法是最好的方法 编辑 我有8GB的RAM,8core服务器,所以我想用线程或进程来处理它们。目前我使用的是进程,到目前为止我还没有发现任何瓶颈。但我在使用线程或进程方面进退两难硬盘的读取速度很可能是这里的瓶颈 因此,根据您需要对数据进行的处理,使用多个线程

我有20个文本文件存储在硬盘中,每个文件包含数百万关于教育组织的信息。假设我有一种方法,可以在循环和进程中迭代文本文件。对于每个文本文件(Factory.startnew())或每个文本文件(process.start())启动每个线程,哪种方法是最好的方法

编辑
我有8GB的RAM,8core服务器,所以我想用线程或进程来处理它们。目前我使用的是进程,到目前为止我还没有发现任何瓶颈。但我在使用线程或进程方面进退两难

硬盘的读取速度很可能是这里的瓶颈

因此,根据您需要对数据进行的处理,使用多个线程可能会很有趣,也可能不有趣(我当然不会使用进程)

但是,最重要的是要确保没有多个线程同时访问同一个物理磁盘,因为这会由于不断切换和查找硬盘磁头而导致速度减慢

我最近做了一些测试,在某些情况下(取决于硬盘和/或pc),操作系统会处理它,不会有太大的区别,但在另一个组合上,速度可能会降低到正常速度的1/10

因此,如果使用多个线程(仅当处理数据的时间比从硬盘读取数据的时间长时才需要!),请确保在某个位置有一个锁,以防止多个线程同时从磁盘读取数据

您可能还希望为此查找内存映射文件

编辑

在使用缓冲区的情况下,可以启动一个线程来连续填充缓冲区,而另一个线程处理数据

edit2(回答米奇):

“进程或线程哪个最好、更快、占用内存更少?”

正如我所说,我不会使用进程(由于额外的开销)。这会留下线程,或者根本没有线程,这取决于需要对数据执行的处理量。如果直接从内存缓冲区读取数据(而不是使用
readline
之类的东西,例如,在这种情况下,所有赌注都将被取消),一个或最多两个线程可能是最好的选择(如果数据处理足够快,则需要进行测试和计时)

至于速度和内存使用:最好的选择(对我来说)是内存映射文件(文件以仅向前模式打开)。这不仅可以利用操作系统磁盘缓存的效率,还可以直接访问内核内存——而在使用(用户)缓冲区时,内存必须从内核复制到用户空间,这需要时间并使用额外的内存

IOCP:可以,但这取决于线程的要求。例如,如果10个线程每次轮流请求100kB(在不同的文件上),则需要10x10ms的seektime,而读取100kB需要不到1ms的时间。未来请求的查找时间取决于IOCP如何处理缓存,这可能与使用内存映射相同,但我认为IOCP在这种情况下不会更快

而使用IOCP,可能也会复制/填充用户空间中的缓冲区(通常可能更难处理)。但我不得不说,在写我的答案时,我在考虑C/C++(使用直接访问内存缓冲区),后来才发现它是C。虽然原理保持不变,但在C#中可能有一种简单的方法可以将异步I/O与IOCP结合使用


至于速度测试和同时避免读取:我已经在大文件上用50多个线程进行了测试(通过内存映射),如果做得正确,就不会损失读取速度。另一方面,当启动一些线程并让它们随机访问硬盘时(即使是在大数据块中),总的读取速度在某些情况下可能会下降到10%,有时甚至根本不会。同一台电脑,其他硬盘,其他结果。

硬盘的读取速度很可能是这里的瓶颈

因此,根据您需要对数据进行的处理,使用多个线程可能会很有趣,也可能不有趣(我当然不会使用进程)

但是,最重要的是要确保没有多个线程同时访问同一个物理磁盘,因为这会由于不断切换和查找硬盘磁头而导致速度减慢

我最近做了一些测试,在某些情况下(取决于硬盘和/或pc),操作系统会处理它,不会有太大的区别,但在另一个组合上,速度可能会降低到正常速度的1/10

因此,如果使用多个线程(仅当处理数据的时间比从硬盘读取数据的时间长时才需要!),请确保在某个位置有一个锁,以防止多个线程同时从磁盘读取数据

您可能还希望为此查找内存映射文件

编辑

在使用缓冲区的情况下,可以启动一个线程来连续填充缓冲区,而另一个线程处理数据

edit2(回答米奇):

“进程或线程哪个最好、更快、占用内存更少?”

正如我所说,我不会使用进程(由于额外的开销)。这会留下线程,或者根本没有线程,这取决于需要对数据执行的处理量。如果直接从内存缓冲区读取数据(而不是使用
readline
之类的东西,例如,在这种情况下,所有赌注都将被取消),则一个或最多两个线程可能是最佳选择(如果数据的处理是