优化 Python 中的文件和数字行数
Posted
技术标签:
【中文标题】优化 Python 中的文件和数字行数【英文标题】:Optimize file and number line count in Python 【发布时间】:2017-12-04 16:19:24 【问题描述】:我有一个包含许多文件夹、文件(.css、.py、.yml 等)和代码行的 python 项目。对于这个项目,我制作了一个名为“统计”的工具,它可以为我提供有关整个项目的信息,例如:
全球统计:
整个项目 :: 32329 行 项目主文件(.py、.yml) :: 8420 行 没有供应商部分的项目 :: 1070 行 核心(src 目录) :: 394 行 核心与项目主文件相比 :: 5 % Kraken 框架 (vendor/*.py) :: 7350 行 主要文件 Python 代码 :: 93 % 供应商 Python 代码 :: 87 % 整个项目大小::37M
为了得到所有这些数字,我主要使用两个函数:
def count_folder_lines(self, path):
files = glob.glob(path, recursive=True)
number = 0
for file in files:
num_lines = sum(1 for line in open(file))
number += num_lines
return number
和
def count_number_of_files(self, path):
files = glob.glob(path, recursive=True)
return len(files)
第一个用于计算文件夹中的行数,第二个用于计算特定文件的数量(例如:src/*.py)。 但是要获得项目的统计数据,需要 4.9 到 5.3 秒,这已经很长了。
有什么方法可以加快速度吗?并行编程或使用 Cython 会改变什么吗?
祝你有美好的一天, 谢谢。
【问题讨论】:
查看文件大小比计算行数要快得多 就我而言,我真的需要行数 问题是你总是被最长的文件所限制。我自己尝试过,对于 20,000 行的文件,可能需要几秒钟。代码行数是一个不会经常改变的数字。因此,我的建议是:要么运行一个脚本来计算与编译并行的结果(如果那是你读出来的时候),要么运行一个后台任务来每 x 分钟或几小时计算一次。在这两种情况下,将结果输出到文件中,然后在需要时直接读取。 【参考方案1】:终于为我找到了最有效的解决方案: 我正在使用多处理模块来并行计算每个文件的行数。
def count_folder_lines(self, path):
"""
Use a buffer to count the number of line of each file among path.
:param path: string pattern of a file type
:return: number of lines in matching files
"""
files = glob.glob(path, recursive=True)
number = 0
for file in files:
f = open(file, 'rb')
bufgen = takewhile(lambda x: x,
(f.raw.read(1024 * 1024) for _ in repeat(None)))
number += sum(buf.count(b'\n') for buf in bufgen if buf)
return number
def count_number_of_files(self, path):
"""
Count number of files for a string pattern
:param path: files string pattern
:return: number of files matching the pattern
"""
files = glob.glob(path, recursive=True)
return len(files)
def multiproc(self):
"""
Multiprocessing to launch several processes to count number of
lines of each string pattern in self.files
:return: List of number of files per string pattern
(list of int).
"""
pool = mp.Pool()
asyncResult = pool.map_async(self.count_folder_lines, self.files)
return asyncResult.get()
使用此解决方案,计数需要约 1.2 秒,而之前需要约 5 秒。
祝你有美好的一天!
【讨论】:
以上是关于优化 Python 中的文件和数字行数的主要内容,如果未能解决你的问题,请参考以下文章