JavaScript: 配列上書きの速度比較

配列の広範囲にわたって値を上書きする速度を比較する企画

# set + subarray vs copyWithin
C言語で例えると`memcpy`のような処理。`set`と`subarray`は古参、`copyWithin`は新参者。配列の前半部に後半部を複写する処理で比較してみる
```js
for(let loop=1<<20,size=2,n=10;n--;loop/=2,size*=4){
	let A=new Uint8Array(size),t=new Date;
	for(let a=loop;a--;)A.set(A.subarray(size>>1,size),0);
	t=new Date-t;
	let u=new Date;
	for(let a=loop;a--;)A.copyWithin(0,size>>1,size);
	console.log(loop,size,t,new Date-u)
}
```
## Chrome
<table>
<tr><th>loop<th>size<th>set+subarray<th>copyWithin
<tr><td>1048576<td>2<td>131<td>76
<tr><td>524288<td>8<td>72<td>38
<tr><td>262144<td>32<td>34<td>19
<tr><td>131072<td>128<td>17<td>11
<tr><td>65536<td>512<td>8<td>7
<tr><td>32768<td>2048<td>6<td>3
<tr><td>16384<td>8192<td>4<td>4
<tr><td>8192<td>32768<td>10<td>8
<tr><td>4096<td>131072<td>23<td>22
<tr><td>2048<td>524288<td>73<td>64
</table>

大した差が無いので今時は`copyWithin`様をこき使う人が多い…かどうかは定かではない
## Firefox
<table>
<tr><th>loop<th>size<th>set+subarray<th>copyWithin
<tr><td>1048576<td>2<td>577<td>83
<tr><td>524288<td>8<td>262<td>42
<tr><td>262144<td>32<td>149<td>20
<tr><td>131072<td>128<td>61<td>13
<tr><td>65536<td>512<td>45<td>7
<tr><td>32768<td>2048<td>21<td>4
<tr><td>16384<td>8192<td>17<td>4
<tr><td>8192<td>32768<td>26<td>13
<tr><td>4096<td>131072<td>29<td>26
<tr><td>2048<td>524288<td>83<td>77
</table>

さすがに関数2つで実装するより1つで実装した方が高速であった…。特に配列長が小さい場合に差が顕著
# fill vs copyWithin(TypedArray)
同値充填の対決。ただし`copyWithin`には制約がある(同値領域必須)
```js
for(let loop=1<<20,size=2,n=10;n--;loop/=2,size*=4){
	let A=new Uint8Array(size),t=new Date;
	for(let a=loop;a--;)A.fill(0);
	t=new Date-t;
	let u=new Date;
	for(let a=loop;a--;)A.fill(0,size>>1);
	u=new Date-u;
	let v=new Date;
	for(let a=loop;a--;)A.copyWithin(0,0);
	v=new Date-v;
	let w=new Date;
	for(let a=loop;a--;)A.copyWithin(0,size>>1);
	console.log(loop,size,t,u,v,new Date-w)
}
```

## Chrome
<table>
<tr><th>loop<th>size<th>fill<th>fill 1/2<th>copyWithin<th>copyWithin 1/2
<tr><td>1048576<td>2<td>75<td>76<td>68<td>69
<tr><td>524288<td>8<td>46<td>40<td>35<td>36
<tr><td>262144<td>32<td>21<td>21<td>19<td>19
<tr><td>131072<td>128<td>11<td>13<td>11<td>10
<tr><td>65536<td>512<td>6<td>5<td>6<td>6
<tr><td>32768<td>2048<td>5<td>3<td>5<td>4
<tr><td>16384<td>8192<td>6<td>4<td>6<td>4
<tr><td>8192<td>32768<td>18<td>7<td>12<td>8
<tr><td>4096<td>131072<td>32<td>17<td>35<td>21
<tr><td>2048<td>524288<td>88<td>33<td>90<td>65
</table>

大差がない。面白味に欠ける奴め
## Firefox
<table>
<tr><th>loop<th>size<th>fill<th>fill 1/2<th>copyWithin<th>copyWithin 1/2
<tr><td>1048576<td>2<td>89<td>78<td>83<td>82
<tr><td>524288<td>8<td>52<td>68<td>41<td>41
<tr><td>262144<td>32<td>42<td>37<td>22<td>20
<tr><td>131072<td>128<td>51<td>40<td>13<td>10
<tr><td>65536<td>512<td>85<td>47<td>7<td>6
<tr><td>32768<td>2048<td>162<td>78<td>6<td>4
<tr><td>16384<td>8192<td>310<td>152<td>7<td>4
<tr><td>8192<td>32768<td>617<td>313<td>12<td>9
<tr><td>4096<td>131072<td>1224<td>603<td>32<td>19
<tr><td>2048<td>524288<td>2432<td>1253<td>94<td>63
</table>

配列長が巨大化するとfillは急激に遅くなってくる。想像の逆をいく結果。オラわくわくしてきたぞ!
# fill vs copyWithin(Array)
回数はTypedArrayより控え目
```js
for(let loop=1<<16,size=2,n=8;n--;loop/=2,size*=4){
	let A=Array(size),t=new Date;
	for(let a=loop;a--;)A.fill(0);
	t=new Date-t;
	let u=new Date;
	for(let a=loop;a--;)A.fill(0,size>>1);
	u=new Date-u;
	let v=new Date;
	for(let a=loop;a--;)A.copyWithin(0,0);
	v=new Date-v;
	let w=new Date;
	for(let a=loop;a--;)A.copyWithin(0,size>>1);
	console.log(loop,size,t,u,v,new Date-w)
}
```
## Chrome
<table>
<tr><th>loop<th>size<th>fill<th>fill 1/2<th>copyWithin<th>copyWithin 1/2
<tr><td>65536<td>2<td>14<td>9<td>21<td>12
<tr><td>32768<td>8<td>5<td>8<td>39<td>18
<tr><td>16384<td>32<td>3<td>3<td>66<td>32
<tr><td>8192<td>128<td>3<td>2<td>128<td>63
<tr><td>4096<td>512<td>6<td>3<td>245<td>130
<tr><td>2048<td>2048<td>13<td>8<td>489<td>242
<tr><td>1024<td>8192<td>25<td>9<td>996<td>486
<tr><td>512<td>32768<td>44<td>18<td>2019<td>969
</table>

歴然たる差
## Firefox
<table>
<tr><th>loop<th>size<th>fill<th>fill 1/2<th>copyWithin<th>copyWithin 1/2
<tr><td>65536<td>2<td>4<td>4<td>5<td>4
<tr><td>32768<td>8<td>7<td>2<td>4<td>2
<tr><td>16384<td>32<td>8<td>3<td>6<td>4
<tr><td>8192<td>128<td>12<td>6<td>13<td>6
<tr><td>4096<td>512<td>24<td>12<td>25<td>12
<tr><td>2048<td>2048<td>59<td>23<td>52<td>25
<tr><td>1024<td>8192<td>101<td>47<td>97<td>49
<tr><td>512<td>32768<td>194<td>93<td>194<td>96
</table>

関数の差がほとんど無い。意味不明である