繁体   English   中英

Python的os.path.join很慢吗?

[英]Is Python's os.path.join slow?

我被告知os.path.join在python中非常慢,我应该使用字符串连接( '%s/%s' % (x, y) )代替。 是否真的存在很大差异?如果是这样,我该如何跟踪它?

$ python -mtimeit -s 'import os.path' 'os.path.join("/root", "file")'
1000000 loops, best of 3: 1.02 usec per loop
$ python -mtimeit '"/root" + "file"'
10000000 loops, best of 3: 0.0223 usec per loop

所以是的,它慢了近50倍。 虽然1微秒仍然没有 ,所以我真的不会考虑其中的差异。使用os.path.join :它是跨平台的,更具可读性且不易出错。

编辑:两个人现在评论说import解释了差异。 这不是真的,因为-s是一个设置标志,因此import不会计入报告的运行时。 阅读文档

我不知道是谁告诉你不要使用它,但他们错了。

  1. 即使它很慢,但程序破坏程度也永远不会慢。 我从来没有注意到它的速度很慢。
  2. 这是跨平台编程的关键。 行分隔符等因平台而异, os.path.join将始终正确地连接路径,而不管平台如何。
  3. 可读性。 每个人都知道join正在做什么。 人们可能不得不为路径的字符串连接做双重操作。

还要注意,函数调用中的句点已知很慢。 相比:

python -mtimeit -s "import os.path;x=range(10)" "os.path.join(x)"
1000000 loops, best of 3: 0.405 usec per loop

python -mtimeit -s "from os.path import join;x=range(10)" "join(x)"
1000000 loops, best of 3: 0.29 usec per loop

因此,只需在函数调用语法中使用句点,就可以减慢40%。

奇怪的是,这两种速度不同:

$ python -mtimeit -s "from os.path import sep;join=sep.join;x=map(str,range(10))" "join(x)"
1000000 loops, best of 3: 0.253 usec per loop

$ python -mtimeit -s "from os.path import join;x=map(str,range(10))" "join(x)"
1000000 loops, best of 3: 0.285 usec per loop

它可能快近50倍,但除非你在CPU内部紧密的内环中进行,否则速度差异根本不重要。 另一方面,可移植性差异将决定您的程序是否可以轻松移植到非Unix平台。

因此,请使用os.path.join除非您已经分析并发现它确实是您程序性能的主要障碍。

您应该使用os.path.join简化可移植性。

我没有把os.path.join (适用于任何数字或部件,在任何平台上)与点字符串格式化两个路径的事情进行比较。

要回答标题中的问题,“ Python的os.path.join是慢吗? ”你必须至少将它与远程类似的函数进行比较,以找出你可以从这样的函数中获得什么样的速度。

正如您在下面看到的,与类似的函数相比, os.path.join没有什么缓慢的

python -mtimeit -s "x = tuple(map(str, range(10)))" "'/'.join(x)"
1000000 loops, best of 3: 0.26 usec per loop

python -mtimeit -s "from os.path import join;x = tuple(range(10))" "join(x)"
1000000 loops, best of 3: 0.27 usec per loop


python -mtimeit -s "x = tuple(range(3))" "('/%s'*len(x)) % x"
1000000 loops, best of 3: 0.456 usec per loop

python -mtimeit -s "x = tuple(map(str, range(3)))" "'/'.join(x)"
10000000 loops, best of 3: 0.178 usec per loop

在这场炙手可热的争议中,我敢于提出:

(我知道,我知道,有时间,但我没有接受过timeit训练,而且我觉得时钟()对于这个案子来说已经足够了)

import os
from time import clock

separ = os.sep
ospath = os.path
ospathjoin = os.path.join

A,B,C,D,E,F,G,H = [],[],[],[],[],[],[],[]
n = 1000

for essays in xrange(100):

    te = clock()
    for i in xrange(n):
        xa = os.path.join('C:\WINNT\system32','Microsoft\Crypto','RSA\MachineKeys')
    A.append(clock()-te)


    te = clock()
    for i in xrange(n):
        xb = ospath.join('C:\WINNT\system32','Microsoft\Crypto','RSA\MachineKeys')
    B.append(clock()-te)


    te = clock()
    for i in xrange(n):
        xc = ospathjoin('C:\WINNT\system32','Microsoft\Crypto','RSA\MachineKeys')
    C.append(clock()-te)


    te = clock()
    for i in xrange(n):
        xd = 'C:\WINNT\system32'+os.sep+'Microsoft\Crypto'+os.sep+'RSA\MachineKeys'
    D.append(clock()-te)


    te = clock()
    for i in xrange(n):
        xe = '%s\\%s\\%s' % ('C:\WINNT\system32','Microsoft\Crypto','RSA\MachineKeys')
    E.append(clock()-te)


    te = clock()
    for i in xrange(n):
        xf = 'C:\WINNT\system32'+separ+'Microsoft\Crypto'+separ+'RSA\MachineKeys'
    F.append(clock()-te)


    te = clock()
    for i in xrange(n):
        xg = os.sep.join(('C:\WINNT\system32','Microsoft\Crypto','RSA\MachineKeys'))
    G.append(clock()-te)


    te = clock()
    for i in xrange(n):
        xh = separ.join(('C:\WINNT\system32','Microsoft\Crypto','RSA\MachineKeys'))
    H.append(clock()-te)

print min(A), "os.path.join('C:\WINNT\system32','Microsoft\Crypto','RSA\MachineKeys')"
print min(B), "ospath.join('C:\WINNT\system32','Microsoft\Crypto','RSA\MachineKeys')"
print min(C), "ospathjoin('C:\WINNT\system32','Microsoft\Crypto','RSA\MachineKeys')"
print min(D), "'C:\WINNT\system32'+os.sep+'Microsoft\Crypto'+os.sep+'RSA\MachineKeys'"
print min(E), "'%s\\%s\\%s' % ('C:\WINNT\system32','Microsoft\Crypto','RSA\MachineKeys')"
print min(F), "'C:\WINNT\system32'+separ+'Microsoft\Crypto'+separ+'RSA\MachineKeys'"
print min(G), "os.sep.join('C:\WINNT\system32','Microsoft\Crypto','RSA\MachineKeys')"
print min(H), "separ.join('C:\WINNT\system32','Microsoft\Crypto','RSA\MachineKeys')"
print 'xa==xb==xc==xd==xe==xf==xg==xh==',xa==xb==xc==xd==xe==xf==xg==xh

结果

0.0284533369465 os.path.join('C:\\ WINNT \\ system32','Microsoft \\ Crypto','RSA \\ MachineKeys')

0.0277652606686 ospath.join('C:\\ WINNT \\ system32','Microsoft \\ Crypto','RSA \\ MachineKeys')

0.0272489939364 ospathjoin('C:\\ WINNT \\ system32','Microsoft \\ Crypto','RSA \\ MachineKeys')

0.00398598145854'C:\\ WINNT \\ system32'+ os.sep +'Microsoft \\ Crypto'+ os.sep +'RSA \\ MachineKeys'

0.00375075603184'%s \\%s \\%s'%('C:\\ WINNT \\ system32','Microsoft \\ Crypto','RSA \\ MachineKeys')

0.00330824168994'C:\\ WINNT \\ system32'+ separ +'Microsoft \\ Crypto'+ separ +'RSA \\ MachineKeys'

0.00292467338726 os.sep.join('C:\\ WINNT \\ system32','Microsoft \\ Crypto','RSA \\ MachineKeys')

0.00261401937956 separ.join('C:\\ WINNT \\ system32','Microsoft \\ Crypto','RSA \\ MachineKeys')

真正

separ = os.sep

ospath = os.path

ospathjoin = os.path.join

每个人都知道os.path.join()的一个不可思议的特性

os.path.join( 'a', 'b' ) == 'a/b'
os.path.join( 'a', '/b' ) == '/b'

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM