线程是否会提高性能?

时间:2012-06-08 18:39:08

标签: c# multithreading

我有一个像这样设置的程序。它是一个.Net Framework 4控制台应用程序。 此程序用于从每个服务器上的每个日志文件(从前一周)收集sc-bytes和cs-bytes。该程序已完成,但需要很长时间才能运行。

foreach (string server in servers)
            {

                foreach (string website in Directory.GetDirectories(server))
                {

                    foreach (string file in Directory.GetFiles(website))
                    {

我只是想知道是否可以使用线程或PLINQ之类的东西来加速这个过程? 如果这会提高性能,我不确定实现它的最佳方法,因为为每个日志文件(甚至每个网站)创建一个新线程似乎不合逻辑,因为拥有那么多线程显然不会提高性能。

如果您需要查看更多代码,请询问,但此程序基本上读取过去七天内创建的每个文件的每一行,添加字节数,然后使用目录条目获取网站名称(来自ID),然后将每个网站的名称和总字节输出到一个文本文件(最终将成为数据库)。 我不需要任何实际代码,只需提供最佳方法(如果可能)以提高性能。

感谢。

6 个答案:

答案 0 :(得分:4)

在像这样的IO绑定任务中(迭代目录和文件并读取它们),瓶颈是磁盘IO,而不是CPU。

并行化(?)这不太可能有助于加快速度,甚至可能会影响性能。

答案 1 :(得分:1)

如果服务器是不同计算机上的磁盘,那么它将提高性能,以并行化每个服务器的请求目录和文件。这是一个服务器在一个线程中运行,可能有1000个服务器在10个线程中运行。您的程序将等待很多IO,网络带宽可能是瓶颈。 更好的方法是在每个执行计数的服务器上安装一个Web服务,然后向每个Web服务询问结果。通过这种方式,网络不会成为瓶颈,您甚至可能以他们已经知道答案的方式制作Web服务(可能使用文件系统观察程序。)

答案 2 :(得分:0)

这实际上取决于使用多个并发线程来提高性能所做的“处理”。很可能是从你的描述中你是I / O绑定的,所以多线程不会有太大帮助,甚至可能更糟。

因此,除非你自己测量,否则答案肯定是“可能”。测量是关键。

答案 3 :(得分:0)

答案取决于几个方面:运行客户端程序的计算机有多少CPU,每个服务器的日志检查是否正确进入每个服务器上的日志文件夹,还是检查每个服务器上的每个目录(和如果是这样的话,文件系统在服务器上有多大,以及文件夹的深度可能会在您的代码片段中通过Directory.GetDirectories进行递归。

你说这项任务需要“很长时间”才能运行。一些基本的Perfmon统计信息和一些TaskManager视图可以帮助您确定在收集数据时使用本地的CPU和磁盘的数量,但我怀疑没有您想象的那么多。

如果您使用.Net的System.Threading同时处理多个远程服务器上的日志,您可能会发现I / O负载在多线程下跨多个服务器的I / O负载分散。然后,尝试从不同服务器同时收集此数据的客户端计算机上可能存在的瓶颈将取决于客户端计算机必须多线程处理线程的CPU数量以及它可以提供的网络带宽,以便通过网络路径接收答案。各种服务器并发。

答案 4 :(得分:0)

Filesystem缓存对数据的访问,尤其是目录和文件信息。因此,如果您使用PLINQ之类的东西,您应该能够看到性能的轻微改进。在控制台应用程序中,我并没有真正看到这一点。如果性能和对性能的感知很重要,那么这种事情将在具有进度和取消的GUI中完成......

但是,我认为您发布的代码存在一些问题。从网站获取文件?这将需要通过线路到另一台服务器的某种请求;我建议将操作异步完成。你没有提供任何人的详细信息来建议你如何做到这一点。

答案 5 :(得分:0)

只有当多个线程的性能优于一个线程的性能时,并行才有意义。

实际结果取决于您拥有的硬件。

如果您的网络速度非常快,并且数据存储在每个服务器的SSD中,您可以尝试并行所有进程。

上面描述的配置在现实世界中是罕见的情况。

在常规环境中检查您的网络利用率。如果它低于20%,您可以尝试并行服务器

与多线程读取相比,HDD(而不是SSD)的顺序读取速度要快得多,因此嵌套循环的并行可能对您有所帮助。

P.S。请勿尝试使用100%的网络。您的IT部门对此不会感到高兴。

相关问题