dis()
が面白い。
js> dis(function(n){ n--, --n, n-=1 }) flags: LAMBDA INTERPRETED main: 00000: argdec 0 00003: pop 00004: decarg 0 00007: pop 00008: getarg 0 00011: one 00012: sub 00013: setarg 0 00016: pop 00017: stop Source notes: 0: 3 [ 3] pcdelta offset 4 2: 7 [ 4] pcdelta offset 9 4: 12 [ 5] assignop
「 -=1 」より「 -- 」のほうが速そうに見える。
js> for(n = 1e6, t = new Date; --n;); print(new Date - t) 858 js> for(n = 1e6, t = new Date; n -= 1;); print(new Date - t) 1123
実際に速いようだ。
js> dis(function() d[k] = d[k] ? d[k]+1 : 1 ) // A flags: LAMBDA EXPR_CLOSURE INTERPRETED main: 00000: name "d" 00003: name "k" 00006: name "d" 00009: name "k" 00012: getelem 00013: ifeq 28 (15) 00016: name "d" 00019: name "k" 00022: getelem 00023: one 00024: add 00025: goto 29 (4) 00028: one 00029: setelem 00030: return 00031: stop Source notes: 0: 12 [ 12] xdelta 1: 12 [ 0] pcbase offset 6 3: 13 [ 1] cond offset 12 5: 22 [ 9] xdelta 6: 22 [ 0] pcbase offset 6 8: 29 [ 7] pcbase offset 29
js> dis(function() d[k] = ++d[k] || 1 ) // B flags: LAMBDA EXPR_CLOSURE INTERPRETED main: 00000: name "d" 00003: name "k" 00006: name "d" 00009: name "k" 00012: incelem 00013: or 17 (4) 00016: one 00017: setelem 00018: return 00019: stop Source notes: 0: 12 [ 12] xdelta 1: 12 [ 0] pcbase offset 6 3: 17 [ 5] pcbase offset 17
js> dis(function() d[k] = -~d[k] ) // C flags: LAMBDA EXPR_CLOSURE INTERPRETED main: 00000: name "d" 00003: name "k" 00006: name "d" 00009: name "k" 00012: getelem 00013: bitnot 00014: neg 00015: setelem 00016: return 00017: stop Source notes: 0: 12 [ 12] xdelta 1: 12 [ 0] pcbase offset 6 3: 15 [ 3] pcbase offset 15
BとCはあまり変わらないが,Aは明らかに効率が悪い。
「短いコードはたいてい速い」のだった。