优化 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 中的文件和数字行数的主要内容,如果未能解决你的问题,请参考以下文章

使用行数中的值更新最后一个字段(awk?)

如何显示行数为 1 或更多的行数中的所有记录?

SecureRandom 数中的算法

统计python文件中的代码,注释,空白对应的行数

Python 读取指定行数

控制台输入多个数字,输出次数最多的数中的最大值