You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何提取20万行文本首字段时awk速度远快于Python?

为什么awk提取文本字段的速度远快于示例中的Python实现

我有一份包含20万行数据的片段列表,每行数据格式如下:

<field 1> <field2>

为提取每行的第一个字段,最初编写的Python实现脚本如下:

import os
import sys
jump = open(sys.argv[1],"r")
clips = open("clips.list","w")
text = jump.readlines()
list_of_clips = str()

for line in text: 
     clip_to_add =   line.split(" ")[0]
     list_of_clips = list_of_clips + clip_to_add +'\n' 

with open ('clips.list', 'w') as file:
file.write (list_of_clips)

jump.close()

相同功能用awk命令(注:原命令存在语法错误,正确写法为awk '{print $1}')执行仅需约1秒,速度远快于上述Python脚本。


速度差距的核心原因

速度差来自两方面:一是示例Python代码存在大量严重的低效设计,二是awk本身就是面向文本流处理高度优化的工具。

  • 示例Python代码的低效点:
    1. 非流式的全量读入开销:调用readlines()会一次性把20万行数据全部加载到内存生成行列表,额外产生大量内存占用和IO等待成本;而awk默认是逐行流式处理,读入一行、处理一行、输出一行,全程内存占用极低,没有全量加载的额外开销。
    2. 字符串反复拼接的O(n²)复杂度开销:Python中字符串是不可变对象,循环中反复执行list_of_clips = list_of_clips + clip_to_add +'\n'时,每次拼接都会生成全新的字符串对象,需要把原有字符串的全部内容复制一遍再追加新内容,20万次循环下来累计的数据复制量会随行数呈平方级增长,这部分是拖慢速度的最主要原因。
    3. 冗余操作与无效开销:代码一开始就以写模式打开了clips.list但从未使用,后续又重新通过with块打开同一文件,产生了无意义的系统调用开销;且with块内的写入语句没有正确缩进,实际运行会直接抛出语法错误;split(" ")会把整行按空格完全切分生成包含所有字段的列表,再取第一个元素,额外构造了完全用不到的后续字段对象,浪费内存和计算时间。
  • awk本身的性能优势:
    awk是专门为文本处理设计的工具,核心逻辑全部由C编写编译为原生机器码执行,没有Python解释器逐行执行字节码的额外开销;其默认的字段分割逻辑经过高度优化,提取第一个字段时不需要切分整行生成所有字段,只需要定位到第一个分隔符的位置就可以直接截断取出目标内容,处理路径极短;同时awk天生适配流式处理,读写缓冲区的优化是几十年迭代沉淀下来的,文本IO效率非常高。

优化后的Python实现性能可接近awk

只要修正上述低效逻辑,Python处理该任务的速度可以追到和awk同一量级,参考优化版本:

import sys

# 逐行流式读写,不加载全量文件到内存
with open(sys.argv[1], "r") as infile, open("clips.list", "w") as outfile:
    for line in infile:
        # 定位第一个空格位置直接截断,不做全量切分
        split_pos = line.find(" ")
        outfile.write(line[:split_pos] + "\n" if split_pos != -1 else line)

内容的提问来源于stack exchange,提问作者ZakS

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.27 17:42:31