LoginSignup
0
0

More than 1 year has passed since last update.

new TextEncoder() するのは最初の1回だけでいい件

Last updated at Posted at 2022-01-28

TextEncoderTextDecoderは、Uint8Arrayと文字列を相互に変換するAPIです。crypto周りのコードでよく使われています。しかし、書き方によってはパフォーマンスが低下する可能性があります。

new TextEncoder()new TextDecoder()を呼び出すタイミング

以下は文字列をUint8Arrayに変換し、SHA-256でハッシュ化する関数です。

よくあるパターン
import * as hex from "https://deno.land/std@0.122.0/encoding/hex.ts";

/** SHA-256を使用して文字列をハッシュ化する関数 */
export async function hash(message: string) {
  // 関数が呼び出されるたびに毎回`new TextEncoder()`されている
  const encoded = new TextEncoder().encode(message);
  const hashBuffer = await crypto.subtle.digest("SHA-256", encoded);
  return new TextDecoder().decode(hex.encode(new Uint8Array(hashBuffer)));
}

一見すると問題ないように見えますが、このコードでは関数が呼び出されるたびに毎回TextEncoderTextDecoderのインスタンスが生成されているため、処理が冗長になっています。

パフォーマンスの観点からは、TextEncoderTextDecoderのインスタンス生成は関数の外で一回だけ行うのが正解です。

import * as hex from "https://deno.land/std@0.122.0/encoding/hex.ts";

// 関数の外側で先にインスタンス生成しておく
const encoder = new TextEncoder();
const decoder = new TextDecoder();
/** SHA-256を使用して文字列をハッシュ化する関数 */
export async function hash(message: string) {
  const encoded = encoder.encode(message);
  const hashBuffer = await crypto.subtle.digest("SHA-256", encoded);
  return decoder.decode(hex.encode(new Uint8Array(hashBuffer)));
}

どれくらいパフォーマンスが向上するのか

ベンチマークを取ってみましょう。ベンチマークには https://jsbench.me/ を使用します。

image.png

結果
毎回インスタンス生成する場合:33.12 ops/s ± 3.24%
先にインスタンス生成する場合:48.21 ops/s ± 1.5%

というわけで、TextEncoderTextDecoderのインスタンスを関数の外側で先に生成する場合は、約35%高速という結果が得られました。

まとめ

  • new TextEncoder()new TextDecoder()を関数の中で呼び出すと遅い
  • 関数の外で呼び出せば、約35%高速化できる
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