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は明らかに効率が悪い。
「短いコードはたいてい速い」のだった。