sistema_progs

Programas para customizar o meu entorno de traballo nos meus equipos persoais
Log | Files | Refs

201711-arithmetic.sh (5690B)


      1 #!/usr/bin/env bash
      2 
      3 if [[ ! ${BLE_VERSION-} ]]; then
      4   source ../../src/benchmark.sh
      5 fi
      6 
      7 #------------------------------------------------------------------------------
      8 # 1 条件コマンドと算術式コマンドのどちらが速いのか?
      9 #
     10 # →算術式コマンド (()) が最も速い。
     11 # 条件コマンドが次に速い。
     12 # 算術式コマンド let は遅い。
     13 #
     14 
     15 function measure1 {
     16   wtype=1 atype=-1
     17   function greater.w0 { [[ wtype -ge 0 ]]; }
     18   function greater.w1 { ((wtype>=0)); }
     19   function greater.w2 { let 'wtype>=0'; }
     20   function greater.a0 { [[ atype -ge 0 ]]; }
     21   function greater.a1 { ((atype>=0)); }
     22   function greater.a2 { let 'atype>=0'; }
     23 
     24   ble-measure 'greater.w0' #  19.20 usec/eval
     25   ble-measure 'greater.w1' #  16.50 usec/eval
     26   ble-measure 'greater.w2' #  20.80 usec/eval
     27   ble-measure 'greater.a0' #  19.40 usec/eval
     28   ble-measure 'greater.a1' #  16.70 usec/eval
     29   ble-measure 'greater.a2' #  21.10 usec/eval
     30 }
     31 
     32 #------------------------------------------------------------------------------
     33 # 2 条件コマンド一個で済ませた方が速いのか、算術式コマンドと条件コマンドに分割した方が速いのか。
     34 #
     35 # →どちらとも言えない。最初の条件が満たされない時には、分割した方が速い。
     36 # 両方が評価される時には単体の条件コマンドの方が微妙に速い。
     37 #
     38 
     39 function measure2 {
     40   arr=(1 2 3)
     41   wtype=1 atype=-1
     42   function greater.w0 { [[ wtype -ge 0 && ${arr[wtype]} ]]; }
     43   function greater.w1 { ((wtype>=0)) && [[ ${arr[wtype]} ]]; }
     44   function greater.a0 { [[ atype -ge 0 && ${arr[atype]} ]]; }
     45   function greater.a1 { ((atype>=0)) && [[ ${arr[atype]} ]]; }
     46   
     47   ble-measure 'greater.w0' #  29.30 usec/eval
     48   ble-measure 'greater.w1' #  30.20 usec/eval
     49   ble-measure 'greater.a0' #  21.00 usec/eval
     50   ble-measure 'greater.a1' #  19.20 usec/eval
     51 }
     52 
     53 #------------------------------------------------------------------------------
     54 # 3 実は代入は算術式の外でやった方が速かったりするのか?
     55 #
     56 # * 算術式の中でやった方が速い。
     57 #   これは実のところ bash の構文解析&評価が、
     58 #   算術式の中と外でどちらの方が速いのかという競争である。
     59 #
     60 # * 流石に直接代入する場合には変数代入の方が速い。
     61 #
     62 
     63 function measure3 {
     64   a=2 b=3 c=4
     65   function assign.d1 { ((x=a*2+b*3-c*4)); }
     66   function assign.d2 { x=$((a*2+b*3-c*4)); }
     67   function assign.c1 { x=0; ((x+=a*2+b*3-c*4)); }
     68   function assign.c2 { x=0; x=$((x+a*2+b*3-c*4)); }
     69 
     70   ble-measure 'assign.d1' # 22.10 usec/eval
     71   ble-measure 'assign.d2' # 23.20 usec/eval
     72   ble-measure 'assign.c1' # 28.10 usec/eval
     73   ble-measure 'assign.c2' # 29.40 usec/eval
     74 
     75   function assign.a1 { ((x=a)); }
     76   function assign.a2 { x=$a; }
     77   function assign.a3 { x=$((a)); } # a に式が含まれている可能性がある時
     78   ble-measure 'assign.a1' # 17.50 usec/eval
     79   ble-measure 'assign.a2' # 16.20 usec/eval
     80   ble-measure 'assign.a3' # 19.40 usec/eval
     81 }
     82 measure3
     83 
     84 #------------------------------------------------------------------------------
     85 # 4 変数代入で配列要素を読み出すのと、再帰算術式で読み出すのでどちらが速いか?
     86 #
     87 # →再帰算術式で読み出すのが断然速い。
     88 # 意外と直接呼び出すのと大した違いはないようだ。
     89 #
     90 
     91 function measure4 {
     92   arr=(1 2 3)
     93   ref='arr[1]'
     94   function element.0 { ((arr[1]>=1)); }
     95   function element.1 { ((ref>=1)); }
     96   function element.2 { val=${arr[1]}; ((val>=1)); }
     97   ble-measure 'element.0' # 19.80 usec/eval
     98   ble-measure 'element.1' # 20.10 usec/eval
     99   ble-measure 'element.2' # 29.50 usec/eval
    100 }
    101 #measure4
    102 
    103 #------------------------------------------------------------------------------
    104 # 5 等値比較
    105 #
    106 # 整数値が標準形 ($value が $((value)) と同じになる) のとき、
    107 # 意外なことに、算術式で比較した方が速い。
    108 #
    109 # 但し、2つの文字列の文字数比較では条件コマンドの方が微妙に速かった。
    110 #
    111 function measure5 {
    112   value=3
    113   function compare.1 { [[ $value == 3 ]]; }
    114   function compare.2 { ((value==3)); }
    115   ble-measure 'compare.1' # 17.40 usec/eval
    116   ble-measure 'compare.2' # 16.80 usec/eval
    117 
    118   lhs=3 rhs=3
    119   function compare.a1 { [[ $lhs == "$rhs" ]]; }
    120   function compare.a2 { ((lhs==rhs)); }
    121   ble-measure 'compare.a1' # 20.10 usec/eval
    122   ble-measure 'compare.a2' # 17.60 usec/eval
    123 
    124   atext=1234 btext=4321
    125   function compare.b1 { [[ ${#atext} == ${#btext} ]]; }
    126   function compare.b2 { ((${#atext}==${#btext})); }
    127   ble-measure 'compare.b1' # 27.60 usec/eval
    128   ble-measure 'compare.b2' # 27.90 usec/eval
    129 }
    130 #measure5
    131 
    132 #------------------------------------------------------------------------------
    133 # 6 条件つきの代入
    134 #
    135 # 条件が満たされるときは単一の算術式にまとめてしまった方が速い。
    136 # また、もし分割するならば ((bar=c)) よりは bar=$c の方が速い。
    137 # 条件が満たされないときは分割した方が良い。
    138 #
    139 
    140 function measure6 {
    141   value=3
    142   function cond-assign.a1 { c=4; ((c>value&&(bar=c))); }
    143   function cond-assign.a2 { c=4; ((c>value)) && ((bar=c)); }
    144   function cond-assign.a3 { c=4; ((c>value)) && bar=$c; }
    145   function cond-assign.b1 { c=3; ((c>value&&(bar=c))); }
    146   function cond-assign.b2 { c=3; ((c>value)) && ((bar=c)); }
    147   function cond-assign.b3 { c=3; ((c>value)) && bar=$c; }
    148   ble-measure 'cond-assign.a1' # 29.10 usec/eval
    149   ble-measure 'cond-assign.a2' # 32.90 usec/eval
    150   ble-measure 'cond-assign.a3' # 31.30 usec/eval
    151   ble-measure 'cond-assign.b1' # 27.70 usec/eval
    152   ble-measure 'cond-assign.b2' # 25.60 usec/eval
    153   ble-measure 'cond-assign.b3' # 25.60 usec/eval
    154 }
    155 #measure6