各位,
我正在优化它以加快进程...
我正在做的是创建一个scandir条目的字典...例如。
fs_data = {}
for item in Path(fqpn).iterdir():
# snipped out a bunch of normalization code
fs_data[item.name.title().strip()] = item
{'file1': <file1 scandisk data>, etc}
然后稍后使用函数来收集数据中的文件和目录的计数。
现在我怀疑使用map的新代码可以优化为比旧代码更快,我怀疑必须运行两次列表解析,一次用于文件,一次用于目录。
但我想不出一种方法来优化它,使其只需运行一次。
有谁能建议一种方法来在新版本中同时对文件和目录求和吗?(如果需要,我可以回退到旧代码)
但我可能在这一点上过度优化了?
欢迎任何反馈。
def new_fs_counts(fs_entries) -> (int, int):
"""
Quickly count the files vs directories in a list of scandir entries
Used primary by sync_database_disk to count a path's files & directories
Parameters
----------
fs_entries (list) - list of scandir entries
Returns
-------
tuple - (# of files, # of dirs)
"""
def counter(fs_entry):
return (fs_entry.is_file(), not fs_entry.is_file())
mapdata = list(map(counter, fs_entries.values()))
files = sum(files for files, _ in mapdata)
dirs = sum(dirs for _, dirs in mapdata)
return (files, dirs)
对比
def old_fs_counts(fs_entries) -> (int, int):
"""
Quickly count the files vs directories in a list of scandir entries
Used primary by sync_database_disk to count a path's files & directories
Parameters
----------
fs_entries (list) - list of scandir entries
Returns
-------
tuple - (# of files, # of dirs)
"""
files = 0
dirs = 0
for fs_item in fs_entries:
is_file = fs_entries[fs_item].is_file()
files += is_file
dirs += not is_file
return (files, dirs)
2条答案
按热度按时间jhdbpxl91#
如果直接Map
is_file
函数,map
* 在这里是 * 快速的:(使用
filter
可能会更快,至少在大多数条目 * 不是 * 文件的情况下。或者使用filter
和is_dir
,如果这对你有用,而且大多数条目不是目录的话。或者使用itertools.filterfalse
和is_file
。或者使用itertools.compress
。另外,* 用list.count
或operator.countOf
对 *True
进行计数,而不是 * 对 * bool进行求和,可能会更快一些,但所有这些想法都需要更多的代码(有些还需要内存),我更喜欢上面的方法。)gcuhipw92#
好吧,Map绝对不是正确答案。
今天早上我起床用timeit创建了一个测试...它有点现实溅到脸上。
如果不进行优化,新的与旧的,新的Map代码大约是2倍的时间。
新版本:0.023185124970041215旧版本:0.011841499945148826
我最终真的上了一点点击诱饵的当,并认为用MAP重写会获得一些更好的效率。
为了完整起见。
虽然我能够缩小差距与一些优化..(谢谢李的建议)
新版本:0.10864979098550975旧版本:0.08246175001841038
很明显,for循环解决方案更容易阅读、更快,而且更简单。
新老之间的速度差异,似乎没有具体的Map。
重复的sum语句增加了.021,并且最大的减速来自第二个fs_entry.is_file,它增加了.06x的计时...