Ell*_*ial 6 python windows performance networking profiling
我有一个程序,可以迭代 SMB 共享网络驱动器(2TB 三星 970 Evo+)上的数千个 PNG 文件,并将它们各自的文件大小相加。不幸的是,它非常慢。对代码进行分析后,发现 90% 的执行时间都花在一个函数上:
filesize += os.path.getsize(png)
其中每个png变量都是 for 循环中单个 PNG 文件(数千个)的文件路径,该循环遍历从中获取的每个 PNG 文件glob.glob()(相比之下,该文件占执行时间的 7.5%)。
代码可以在这里找到: https: //pastebin.com/SsDCFHLX
显然,通过网络获取文件大小的速度非常慢,但我不确定是什么。有什么方法可以提高性能吗?使用时间也一样长 filesize += os.stat(png).st_size。
当PNG文件存储在本地计算机上时,速度不是问题。当文件存储在我使用千兆位以太网电缆通过本地网络访问的另一台计算机上时,这尤其成为一个问题。两者都运行 Windows 10。
[2022年8月21日更新]
这次我用 10 GB 网络连接再次尝试,发现了一些有趣的事情。我第一次在网络共享上运行代码时,分析器如下所示:
但如果我之后再次运行它,则glob()占用的时间明显减少,而效果getsize()却大致相同:
如果我使用存储在本地 NVMe 驱动器 (WD SN750) 而不是 newtwork 驱动器上的 PNG 文件来运行此代码,则分析器如下所示:
似乎一旦它在网络共享上第二次运行,某些内容就会被缓存,从而允许glob()在网络共享上运行得更快,其速度与在本地 NVMe 驱动器上运行的速度大致相同。但getsize()仍然非常慢,大约是本地速度的 1/10。
有人可以帮助我理解这两点:
getsize()网络共享速度慢很多?有什么办法可以加快速度吗?glob()第一次在网络共享上速度很慢,但之后立即再次运行它时却没有?小智 3
我不知道为什么getsize()它与网络上的速度一样慢,但是为了加快速度,您可以尝试同时调用它:
import os
from multiprocessing.pool import ThreadPool
def get_total_filesize_concurrently(paths):
total = 0
with ThreadPool(10) as pool:
for size in pool.imap_unordered(lambda path: os.path.getsize(path), paths):
total += size
return total
print(get_total_filesize_concurrently([
"E:\Path\To\File.txt",
"E:\Path\To\File2.txt"
"E:\Path\To\File3.txt"
...
]))
Run Code Online (Sandbox Code Playgroud)
您还可以调整定义的线程数量,ThreadPool(10)以进一步提高性能。
| 归档时间: |
|
| 查看次数: |
596 次 |
| 最近记录: |