deasty
V2EX  ›  问与答

如何提高 awk 的计算速度

  •  
  •   deasty · Jun 18, 2020 via iPhone · 4541 views
    This topic created in 2167 days ago, the information mentioned may be changed or developed.
    有一个 50M 的文本,90 多万行,每行有个数字,用 shell 写个脚本用 awk 取数后经过一个幂运算再输出到新文本,7 个小时过去了,才完成 20 多万行,如何能提高这个效率?
    Supplement 1  ·  Jun 18, 2020
    原始数据
    BJ|986|daxingqu
    GZ|959|tianhequ
    …省略 90 万行
    我的需求结果是把每行的数字乘以 1024 的平方后放在行首,结果如下
    1033895936|BJ|986|daxingqu
    1005584384|GZ|959|tianhequ
    …省略 90 万行
    Supplement 2  ·  Jun 18, 2020
    $./get.sh input.txt output.txt
    $more get.sh
    #!/bin/sh
    m =$(wc -l $1 |awk {'print $1'})
    for ((i = 1;i <=$m;i ++))
    do
    sed -n ${i}p $1 |awk -F "|" {'print $2*1024^2'} |tr "\n" "|">>$2&&sed -n ${i}p $1 >>$2
    done
    Supplement 3  ·  Jun 18, 2020
    哎,解决了,自己犯 2 了……
    26 replies    2020-06-18 19:13:42 +08:00
    amoia50
        1
    amoia50  
       Jun 18, 2020 via iPhone
    python 不香吗[狗头]
    iintothewind
        2
    iintothewind  
       Jun 18, 2020
    xargs, parallel 都可以并行处理 可以试试
    rrfeng
        3
    rrfeng  
       Jun 18, 2020 via Android
    每行只有一个数字?没别的?
    运算具体是啥?

    你这相当于没说,咋分析
    delectate
        4
    delectate  
       Jun 18, 2020
    7 小时大约 25200s,处理 20w 行,一秒 10 行,不够快。
    要么 py+多进程,要么像楼上说的并行处理,或者干脆把文件拆分,然后多个一起跑也行。
    FrankHB
        5
    FrankHB  
       Jun 18, 2020
    为什么非要制造瓶颈?这种简单任务你用 C 临时糊个都不用几分钟,省下几个小时不香吗……
    lululau
        6
    lululau  
       Jun 18, 2020 via iPhone
    单行命令的文本处理,python 真不香,sed awk perl ruby 不知道香到哪里去了,你也配叫脚本语言
    CEBBCAT
        7
    CEBBCAT  
       Jun 18, 2020 via Android
    上次可能是计算 int64 的移位,awk 确实没有 Python 快,我跑起来一会儿 awk 了发现还没跑好,然后再开了一个终端去写 Python,等我写完跑出结果了 awk 还是没有算完。

    楼上这么说有什么依据吗?
    momocraft
        8
    momocraft  
       Jun 18, 2020
    "经过一个幂运算" 是 awk 自己的计算吗?
    layorlayor
        9
    layorlayor  
       Jun 18, 2020
    把代码贴出来吧。感觉不应该这么慢
    lululau
        10
    lululau  
       Jun 18, 2020
    @CEBBCAT 举两个最简单也最常见的例子:

    文本替换:

    sed 's///'
    gawk 'gsub()'
    perl -pe 's///'
    ruby -pe 'gsub!()'

    取一列并做变换:

    gawk '{print $1*2}'
    perl -alne 'print $F[0]*2'
    ruby -ane 'puts $F[0].to_i * 2'

    欢迎楼下用 python 弄一个更简单的写法来打脸

    还忘了说最近看到的一个行列结构文本处理的瑞士军刀 miller
    ylrshui
        11
    ylrshui  
       Jun 18, 2020 via iPhone
    估计 excel 都比这快
    thedog
        12
    thedog  
       Jun 18, 2020
    awk 不应该那么慢吧,很多时候,这种简单任务,awk 比 python 快的。
    runze
        13
    runze  
       Jun 18, 2020
    代码贴出来看看? awk 虽然不算快,但绝不至于慢到这种程度
    TimePPT
        14
    TimePPT  
    PRO
       Jun 18, 2020 via Android
    这么规整的结构,还要做计算。pandas 很香的
    ygtq
        15
    ygtq  
       Jun 18, 2020
    show me the code :)
    xlcoder166
        16
    xlcoder166  
       Jun 18, 2020
    现有代码不变的思路 - 分治

    1. 拆原文件至 90W / n ( CPU 核心数)个文件
    2. shell 并行处理 拆分的文件
    youngster
        17
    youngster  
       Jun 18, 2020
    估计不是 awk 慢,是你运算太慢,换个换个运算快的语言应该都能解决
    layorlayor
        18
    layorlayor  
       Jun 18, 2020
    awk -F'|' '{print $2*1024*1024"|"$0}' 这个很快呀
    layorlayor
        19
    layorlayor  
       Jun 18, 2020   ❤️ 1
    awk -F'|' '{print $2*1024*1024"|"$0} input.txt > output.txt
    Vegetable
        20
    Vegetable  
       Jun 18, 2020
    你这脚本写的是个啥,处理单行文本还有 for 循环?看着就害怕
    Vegetable
        21
    Vegetable  
       Jun 18, 2020
    btw,1024*1024 就是 2**20
    klesh
        22
    klesh  
       Jun 18, 2020
    测试命令:
    seq 0 10000 | awk '{print "foo|"$1"|bar"}' > test.txt
    time awk -F'|' '{print $2*1024*1024"|"$0}' test.txt

    结果:
    10484711424|foo|9999|bar
    10485760000|foo|10000|bar

    ________________________________________________________
    Executed in 76.44 millis fish external
    usr time 54.70 millis 0.00 micros 54.70 millis
    sys time 21.51 millis 962.00 micros 20.54 millis


    硬件
    CPU: Intel(R) Core(TM) i7-6700HQ CPU @ 2.60GHz
    SSD: SanDisk SD8SB8U5
    Kelan
        23
    Kelan  
       Jun 18, 2020
    这么小的文本跑 7 个小时有点离谱了把。
    0x11901
        24
    0x11901  
       Jun 18, 2020
    说实话每次遇到这种问题总有一群人说用 python 不香么……

    真是应了那句老话:当你手上有一把锤子的时候,看所有的东西都是钉子
    freelancher
        25
    freelancher  
       Jun 18, 2020
    结果是个啥。得说呀。还是说附言二就解决了?
    Semidio
        26
    Semidio  
       Jun 18, 2020
    @freelancher #24 注意看 18L 和附言 2 的区别
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Solana   ·   1354 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 74ms · UTC 17:03 · PVG 01:03 · LAX 10:03 · JFK 13:03
    ♥ Do have faith in what you're doing.