在 Python 中优化文件和数字行数
Optimize file and number line count in Python
我有一个 python 项目,其中包含许多文件夹、文件(.css、.py、.yml 等)和代码行。对于这个项目,我制作了一个名为 "statistics" 的工具,它为我提供了有关整个项目的信息,例如:
Global statistics:
Entire project :: 32329 lines
Project main files (.py, .yml) :: 8420 lines
Project without vendor part :: 1070 lines
Core (src directory) :: 394 lines
Core compared to project main files :: 5 % Kraken
Framework (vendor/*.py) :: 7350 lines
Main files Python code :: 93 %
Vendor Python code :: 87 %
Entire project size :: 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 会改变什么吗?
祝你有愉快的一天,
谢谢。
终于找到了对我来说最有效的解决方案:
我正在使用多处理模块并行计算每个文件的行数。
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 项目,其中包含许多文件夹、文件(.css、.py、.yml 等)和代码行。对于这个项目,我制作了一个名为 "statistics" 的工具,它为我提供了有关整个项目的信息,例如:
Global statistics:
Entire project :: 32329 lines
Project main files (.py, .yml) :: 8420 lines
Project without vendor part :: 1070 lines
Core (src directory) :: 394 lines
Core compared to project main files :: 5 % Kraken Framework (vendor/*.py) :: 7350 lines
Main files Python code :: 93 %
Vendor Python code :: 87 %
Entire project size :: 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 会改变什么吗?
祝你有愉快的一天, 谢谢。
终于找到了对我来说最有效的解决方案: 我正在使用多处理模块并行计算每个文件的行数。
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 秒。
祝你有个愉快的一天!