色々な実装でbase64文字列の復号速度を検証していきます。特に難しい事はせず、どの組み込み関数やObjectを利用するかの違いが焦点となります。返り値はUint8Arrayとします。
//復号関数群
let u8map=s=>{s=s.replace(/[^A-Za-z\d+/]/g,"");
var a=62,b=0,c,d=s.length,A=new Uint8Array(123),B=new Uint8Array((d+2>>>2)*3-[0,0,2,1][d&3]);
for(A[43]=a;A[--a>51?a-4:a>25?a+71:a+65]=a;);
for(A[47]=63;a<d;B[b++]=c&255)c=A[s.charCodeAt(a++)]<<18|A[s.charCodeAt(a++)]<<12|A[s.charCodeAt(a++)]<<6|A[s.charCodeAt(a++)],B[b++]=c>>16,B[b++]=c>>8&255;
return B
},hmap=s=>{s=s.replace(/[^A-Za-z\d+/]/g,"").split("");
for(var a=62,b=0,c,d=s.length,A={"+":62,"/":63},B=new Uint8Array((d+2>>>2)*3-[0,0,2,1][d&3]);A[String.fromCharCode(--a>51?a-4:a>25?a+71:a+65)]=a;);
for(;a<d;B[b++]=c&255)c=A[s[a++]]<<18|A[s[a++]]<<12|A[s[a++]]<<6|A[s[a++]],B[b++]=c>>16,B[b++]=c>>8&255;
return B
},index=s=>{s=s.replace(/[^A-Za-z\d+/]/g,"");
for(var a=62,b=0,c,d=s.length,A="+/",B=new Uint8Array((d+2>>>2)*3-[0,0,2,1][d&3]);a;)A=String.fromCharCode(--a>51?a-4:a>25?a+71:a+65)+A;
for(s+="AA";a<d;B[b++]=c&255)c=A.indexOf(s[a++])<<18|A.indexOf(s[a++])<<12|A.indexOf(s[a++])<<6|A.indexOf(s[a++]),B[b++]=c>>16,B[b++]=c>>8&255;
return B
},b2a=s=>{s=btoa(s);
for(var a=s.length,B=new Uint8Array(a);a;)B[--a]=s.charCodeAt(a);
return B
},
//復号対象
b64="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".repeat(1e4),
//検証用変数
round=100,f=a=>a.charCodeAt();
//実践
for(let fn of[u8map,hmap,index,b2a,a=>Uint8Array.from(btoa(a),f)]){
let a=round,t=new Date;
for(;a--;)fn(b64);
console.log(new Date-t)
}
結果、最速を誇ったのがb2a
だ(btoa
+ for loop)! さすが組み込み関数様だぜ!
それに続くのがu8map
([A-Za-z0-9/+]
をUint8Array
で数値変換するC言語風の実装)。
栄光の3番手につけたのがhmap
だ(昔ながらの連想配列を利用したもの)。
不名誉ある4番手はindex
(indexOf
連発で遅いに決まっている)。
そしてUint8Array.from
が断然ダントツぶっちぎり圧倒的桁違いにクソ遅い! しかし記述が簡単だから許してあげようぜ!(許さん)
ただし復号しようとするbase64文字列が極端に短い場合や長い場合は結果が変わってくるっぽい。長い程u8map
が優勢になり、ある時点から最速になる(Google Chromeの場合)
codegolf
encoder 162 bytes
<input type=file oninput="with(new FileReader)readAsBinaryString(files[0]),onload=b=>a.href=top.URL.createObjectURL(new Blob([btoa(result)]))"><a download id=a>DL
decoder 158 bytes
<input type=file oninput="files[0].text().then(b=>a.href=top.URL.createObjectURL(new Blob([Uint8Array.from(atob(b),b=>b.charCodeAt())])))"><a download id=a>DL
いずれもFile処理専用