0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

JavaScript: base64高速化(2)

0
Posted at

base64符号化/復号の高速化の続編。以下の4種類で試しやがっときました。果たして更なる高速化を達成できるのか?

  1. 入出力ともにTypedArray利用
  2. 入力はDataView、出力はTypedArray利用
  3. 入力はTypedArray、出力はDataView利用
  4. 入出力ともにDataView利用

ちなみに1は前回の実装。

//// base64 encode
//TypedArray + TypedArray
const b2a=A=>{
	var a=62,b=0,c,z=A.length,B=new Uint8Array((z*4+2)/3),C=new Uint8Array(64);
	for(C[a]=43;a;)C[--a]=a>51?a-4:a>25?a+71:a+65;
	for(C[63]=47;a<z;B[b++]=C[63&c])c=A[a++]<<16|A[a++]<<8|A[a++],B[b++]=C[c>>18],B[b++]=C[63&c>>12],B[b++]=C[63&c>>6];
	return new TextDecoder().decode(B)
},
//DataView + TypedArray
B2a=A=>{
	var a=62,b=0,c,z=A.length,y=z-3,B=new Uint8Array((z*4+2)/3),C=new Uint8Array(64),D=new DataView(A.buffer||new Uint8Array(A).buffer);
	for(C[a]=43;a;)C[--a]=a>51?a-4:a>25?a+71:a+65;
	for(C[63]=47;a<y;a+=3)c=D.getUint32(a)>>8,B[b++]=C[c>>18],B[b++]=C[c>>12&63],B[b++]=C[c>>6&63],B[b++]=C[c&63];
	for(;a<z;B[b++]=C[c&63])c=A[a++]<<16|A[a++]<<8|A[a++],B[b++]=C[c>>18],B[b++]=C[c>>12&63],B[b++]=C[c>>6&63];
	return new TextDecoder().decode(B)
},
//TypedArray + DataView
b2A=A=>{
	var a=62,b=0,c,z=A.length,y=z-3,B=new Uint8Array((z*4+2)/3),C=new Uint8Array(64),E=new DataView(B.buffer);
	for(C[a]=43;a;)C[--a]=a>51?a-4:a>25?a+71:a+65;
	for(C[63]=47;a<y;b+=4)c=A[a++]<<16|A[a++]<<8|A[a++],E.setUint32(b,C[c>>18]<<24|C[c>>12&63]<<16|C[c>>6&63]<<8|C[c&63]);
	for(;a<z;B[b++]=C[c&63])c=A[a++]<<16|A[a++]<<8|A[a++],B[b++]=C[c>>18],B[b++]=C[c>>12&63],B[b++]=C[c>>6&63];
	return new TextDecoder().decode(B)
},
//DataView + DataView
B2A=A=>{
	var a=62,b=0,c,z=A.length,y=z-3,B=new Uint8Array((z*4+2)/3),C=new Uint8Array(64),D=new DataView(A.buffer||new Uint8Array(A).buffer),E=new DataView(B.buffer);
	for(C[a]=43;a;)C[--a]=a>51?a-4:a>25?a+71:a+65;
	for(C[63]=47;a<y;a+=3)c=D.getUint32(a)>>8,E.setUint32(b,C[c>>18]<<24|C[c>>12&63]<<16|C[c>>6&63]<<8|C[c&63]),b+=4;
	for(;a<z;B[b++]=C[c&63])c=A[a++]<<16|A[a++]<<8|A[a++],B[b++]=C[c>>18],B[b++]=C[c>>12&63],B[b++]=C[c>>6&63];
	return new TextDecoder().decode(B)
},
//////// base64 decode
//TypedArray + TypedArray
a2b=A=>{
	if(typeof A=="string")A=new TextEncoder().encode(A.replace(/[^A-Za-z\d/+]/g,""));
	var a=62,b=0,c,z=A.length,B=new Uint8Array((z+2>>>2)*3-"0021"[z&3]),C=new Uint8Array(123);
	for(C[43]=a;C[--a>51?a-4:a>25?a+71:a+65]=a;);
	for(C[47]=63;a<z;B[b++]=255&c)c=C[A[a++]]<<18|C[A[a++]]<<12|C[A[a++]]<<6|C[A[a++]],B[b++]=c>>16,B[b++]=255&c>>8;
	return B
},
//DataView + TypedArray
A2b=A=>{
	if(typeof A=="string")A=new TextEncoder().encode(A.replace(/[^A-Za-z\d/+]/g,""));
	var a=62,b=0,c,z=A.length,y=z-4,B=new Uint8Array((z+2>>>2)*3-"0021"[z&3]),C=new Uint8Array(123),D=new DataView(A.buffer||new Uint8Array(A).buffer);
	for(C[43]=a;C[--a>51?a-4:a>25?a+71:a+65]=a;);
	for(C[47]=63;a<y;a+=4)c=D.getUint32(a),c=C[c>>>24]<<18|C[c>>16&255]<<12|C[c>>8&255]<<6|C[c&255],B[b++]=c>>16,B[b++]=255&c>>8,B[b++]=255&c;
	for(;a<z;B[b++]=255&c)c=C[A[a++]]<<18|C[A[a++]]<<12|C[A[a++]]<<6|C[A[a++]],B[b++]=c>>16,B[b++]=255&c>>8;
	return B
},
//TypedArray + DataView
a2B=A=>{
	if(typeof A=="string")A=new TextEncoder().encode(A.replace(/[^A-Za-z\d/+]/g,""));
	var a=62,b=0,c,z=A.length,y=z-4,B=new Uint8Array((z+2>>>2)*3-"0021"[z&3]),C=new Uint8Array(123),E=new DataView(B.buffer);
	for(C[43]=a;C[--a>51?a-4:a>25?a+71:a+65]=a;);
	for(C[47]=63;a<y;b+=3)E.setUint32(b,C[A[a++]]<<26|C[A[a++]]<<20|C[A[a++]]<<14|C[A[a++]]<<8);
	for(;a<z;B[b++]=255&c)c=C[A[a++]]<<18|C[A[a++]]<<12|C[A[a++]]<<6|C[A[a++]],B[b++]=c>>16,B[b++]=255&c>>8;
	return B
},
//DataView + DataView
A2B=A=>{
	if(typeof A=="string")A=new TextEncoder().encode(A.replace(/[^A-Za-z\d/+]/g,""));
	var a=62,b=0,c,z=A.length,y=z-4,B=new Uint8Array((z+2>>>2)*3-"0021"[z&3]),C=new Uint8Array(123),D=new DataView(A.buffer||new Uint8Array(A).buffer),E=new DataView(B.buffer);
	for(C[43]=a;C[--a>51?a-4:a>25?a+71:a+65]=a;);
	for(C[47]=63;a<y;a+=4)c=D.getUint32(a),E.setUint32(b,C[c>>>24]<<26|C[c>>16&255]<<20|C[c>>8&255]<<14|C[c&255]<<8),b+=3;
	for(;a<z;B[b++]=255&c)c=C[A[a++]]<<18|C[A[a++]]<<12|C[A[a++]]<<6|C[A[a++]],B[b++]=c>>16,B[b++]=255&c>>8;
	return B
};

64万文字分を100回ずつ計測しました。符号化では1と2がほぼ大体かなり概ね同程度、3がそれより約5%高速、4が約10%高速という感じです。
復号では1と2が同程度、3と4はそれより若干遅かったり速かったりします。
ちなみに今回の実装でbase64符号化はArrayTypedArrayを受け付け、出力は文字列、base64復号は文字列かArrayTypedArrayを受け付け、Uint8Array出力となります

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?