2

我有一个这样的程序。它是一个 .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 之类的东西来加速该过程?如果这会提高性能,我不确定实现它的最佳方法,因为为每个日志文件(甚至每个网站)设置一个新线程似乎不合逻辑,因为拥有这么多线程显然不会提高性能。

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

谢谢。

4

6 回答 6

4

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

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

于 2012-06-08T18:42:06.927 回答
1

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

于 2012-06-08T18:58:17.907 回答
0

Paralleling makes sense only if performance of several threads is better than performance of one thread.

Actual result depends on hardware you have.

If you have very fast network and data is stored in SSDs in every server you may try to parallel all your processes.

configuration described above is rare case in real world.

In regular environment check your network utilization. If it is below 20% you may try paralleling for servers.

Sequential read is much faster with HDD (not SSD) comparing to multi-threaded read so paralleling of nested loops unlikely will help you.

P.S. Do not try to utilize 100% of your network. Your IT will not be happy about that.

于 2012-06-08T20:20:26.560 回答
0

使用多个并发线程是否会提高性能实际上取决于完成的“处理”。根据您的描述,您很可能受 I/O 限制,因此多线程不会有太大帮助,甚至可能更糟。

因此,除非您自己衡量,否则答案是肯定的“也许”。测量是这里的关键。

于 2012-06-08T18:42:16.787 回答
0

答案取决于几件事:运行客户端程序的机器有多少 CPU,log-checking-per-server 是直接进入每台服务器上的日志文件夹还是检查每台服务器上的每个目录(如果是,如何文件系统在服务器上的大小),以及文件夹在代码片段中可能通过 Directory.GetDirectories 递归的深度。

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

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

于 2012-06-08T19:09:14.267 回答
0

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

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

于 2012-06-08T19:11:37.840 回答