MST

星途 面试题库

面试题:Python re模块在处理大文本及性能优化方面的应用

给定一个非常大的文本文件(假设文件大小为1GB,内容为大量的日志记录,每行日志格式为'时间戳:[INFO|ERROR|WARN] - 具体信息'),需要使用Python的re模块统计出每种日志级别(INFO、ERROR、WARN)出现的次数。请考虑如何优化性能,避免内存溢出等问题,编写代码实现,并说明优化思路及采取的具体措施。
45.1万 热度难度
编程语言Python

知识考点

AI 面试

面试题答案

一键面试

代码实现

import re


def count_log_levels(file_path):
    info_count = 0
    error_count = 0
    warn_count = 0
    pattern_info = re.compile(r'^.*:INFO - ')
    pattern_error = re.compile(r'^.*:ERROR - ')
    pattern_warn = re.compile(r'^.*:WARN - ')
    with open(file_path, 'r', encoding='utf-8') as f:
        for line in f:
            if pattern_info.match(line):
                info_count += 1
            elif pattern_error.match(line):
                error_count += 1
            elif pattern_warn.match(line):
                warn_count += 1
    return {
        'INFO': info_count,
        'ERROR': error_count,
        'WARN': warn_count
    }


你可以使用以下方式调用这个函数:

file_path = 'your_large_file.log'
result = count_log_levels(file_path)
print(result)

优化思路及具体措施

  1. 逐行读取
    • 思路: 由于文件非常大,一次性将整个文件读入内存可能会导致内存溢出。因此,使用with open逐行读取文件,每次只在内存中处理一行数据,大大减少了内存占用。
    • 具体措施:在count_log_levels函数中,通过for line in f的方式逐行遍历文件对象f
  2. 预编译正则表达式
    • 思路:正则表达式在每次调用re.match等函数时,如果没有预编译,Python会进行一些初始化工作,这会带来额外的开销。预编译正则表达式可以提高匹配效率。
    • 具体措施:在函数开始部分,使用re.compile分别对INFOERRORWARN的匹配模式进行预编译,得到pattern_infopattern_errorpattern_warn,后续使用这些预编译的模式进行匹配。