[Python-Dev] PEP 471 (scandir): Poll to choose the implementation (full C or C+Python)
Victor Stinner
victor.stinner at gmail.com
Fri Feb 13 12:48:10 CET 2015
2015-02-13 11:52 GMT+01:00 Serhiy Storchaka <storchaka at gmail.com>:
> You can try to make Python implementation faster if
>
> 1) Don't set attributes to None in constructor.
The class uses __slots__. Setting attributes in the class body is
forbidden when __slots__ is used.
> 3) Or pass DirEntry to _scandir:
>
> def scandir(path):
> yield from _scandir(path, DirEntry)
I implemented that and there is no major change (1.3x faster => 1.5x,
it's still far from 3.5x faster seen with the C implementation).
I analyzed numbers (on my desktop PC, HDD, ext4):
- readdir: 380 ns
- os.stat: 1500 ns
- DirEntry(C): 100 ns
- DirEntry (Py): 530 ns (5.3x slower)
- is_dir(C): 75 ns
- is_dir (Py): 260 ns (3.5x slower)
listdir+stat benchmarks takes (readdir + stat) nanoseconds
scandir+is_dir takes (readdir + DirEntry + is_dir) nanoseconds
=> scandir+is_dir is faster than list+stat if (DirEntry+is_dir) is
faster than (stat).
Callig os.stat takes 1500 ns, while readdir() only provides
informations required by the benchmark. So if DirEntry +
DirEntry.is_dir is faster than 1500 ns, we won :-)
The Python implementation takes 790 ns, but the C implementation takes
only 175 ns! (4.5x faster)
I don't think that any Python performance trick can reduce the Python
overhead to make the C+Python implementation interesting compared to
os.listdir+os.stat. We are talking about nanoseconds, Python cannot
beat C at this resolution.
Victor
More information about the Python-Dev
mailing list