2005-12-11

When perl is not quite fast enough

来源: 本站收集整理 作者:佚名 评论 0 条
 
  • Fetch the address of $a
  • Place the thing on the top of stack into that address
  • Computers are fast at simple things like addition. But there is quite a lot of overhead involved in keeping track of "which op am I currently performing" and "where is the next op", and this book-keeping often swamps the time taken to actually run the ops. So often in perl it's the number of ops your program takes to perform its task that is more important than the CPU they use or the RAM it needs. The hit list is

    1. Ops
    2. CPU
    3. RAM

    So what were my example code snippets that I Benchmarked?

    It was code to split a line of hex (54726164696e67207374796c652f6d61) into groups of 4 digits (5472 6164 696e ...) , and convert each to a number

        sub orig {
    
           map {hex $_} $line =~ /(....)/g;
    
        }
        sub new {
    
           unpack "n*", pack "H*", $line;
    
        }

    The two produce the same results:


    orignew
    21618, 24932, 26990, 26400, 29556, 31084, 25903, 28001, 26990, 29793, 26990, 24930, 26988, 26996, 31008, 26223, 29216, 29552, 25957, 2564621618, 24932, 26990, 26400, 29556, 31084, 25903, 28001, 26990, 29793, 26990, 24930, 26988, 26996, 31008, 26223, 29216, 29552, 25957, 25646

    but the first one is much slower. Why? Following the data path from right to left, it starts well with a global regexp, which is only one op and therefore a fast way to generate a list of the 4 digit groups. But that map block is actually an implicit loop, so for each 4 digit block it iterates round and repeatedly calls hex. Thats at least one op for every list item.

    Whereas the second one has no loops in it, implicit or explicit. It uses one pack to convert the hex temporarily into a binary string, and then one unpack to convert that string into a list of numbers. n is big endian 16 bit quantities. I didn't know that - I had to look it up. But when the profiler told me that this part of the original code was a performance bottleneck, the first think that I did was to look at the the pack docs to see if I could use some sort of pack/unpack as a speedier replacement.

    Ops are bad, m'kay

    You can ask perl to tell you the ops that it generates for particular code with the Terse backend to the compiler. For example, here's a 1 liner to show the ops in the original code:

    $ perl -MO=Terse -e'map {hex $_} $line =~ /(....)/g;'
    共13页: 上一页 [1] [2] [3] [4] [5] [6] [7] [8] 9 [10] [11] [12] [13] 下一页

    (本文仅表明作者个人观点,不代表本站及其管理员立场.) 推荐 收藏 投稿 打印 返回 关闭
    上一篇:被百度降权后,网站该怎么办?  
    下一篇:SQL Server2000数据库文件损坏时如何恢复
      评论加载中…
     推荐文章
       

    网站首页  -  网站地图 -   站长论坛  -  网站投稿  -    -  网站管理
    Copyright © 2008 芜湖站长站 All Rights Reserved 皖ICP备07500611号