Node.js 6系と8系の LTS でパフォーマンス比較してみた

Node.js 8.9.0 が LTS としてリリースされて数ヶ月がたち

そろそろ実戦投入していきたいのでパフォーマンスを計測/比較してみた.

実行環境

  • AWS EC2 m3.medium インスタンス
  • Ubuntu 16.04.3
Node.js
  • 6系 - 6.12.3
  • 8系 - 8.9.4

ベンチマークコード

シンプルに json を返すだけの処理で実施.

var http = require('http');

http.createServer(function (req, res) {
    res.writeHead(200, {'Content-Type': 'application/json'});
    res.write(JSON.stringify({result: 'success'}));
    res.end();
}).listen(8080);

github.com

パフォーマンステストの方法

  • Apache Bench を使用
  • 10万リクエスト
  • 並列数を変えながら(10 ~ 5000), かかった時間を計測
  • 各並列数で3回実行した平均値を計測値とする
 ab -n 100000 -c 5000 http://ec2-xxx/

途中で Too many open files が出たので ulimit -n 10240 で上限値を増やした.

結果

f:id:morugu:20180121170002p:plain

f:id:morugu:20180121170015p:plain

まとめ

平均で 14%のパフォーマンス向上 が確認できた.

実戦投入に向けて

  • Cluster を使用
  • 重い処理
  • DBアクセス
  • シナリオテスト

あたりの検証もしていきたい.

おまけ

「なんで速くなってるの?」というところで

Node.js 本体とその実行環境である V8 JavaScript engine が改善されているからなのだけど

それらが具体的にどう改善されたかわかるまとめ.

(このあたりのコードを読んだ解説記事も書きたい)

http: improve outgoing string write performance by mscdex · Pull Request #13013 · nodejs/node · GitHub

lib,src: improve writev() performance for Buffers by mscdex · Pull Request #13187 · nodejs/node · GitHub

querystring: improve querystring unescapeBuffer perf by jseijas · Pull Request #12525 · nodejs/node · GitHub

stream: improve readable push performance by mscdex · Pull Request #13113 · nodejs/node · GitHub

v8project.blogspot.jp

react-native run-* で error during initialization or failure to call AppRegistry.registerComponent の対策

エラーログ

APP_NAME has not been registered.
This is either due to a required() error during initialization or failure to call AppRegistry.registerComponent

対策

node プロセスが干渉しているので kill する.

$ ps aux | grep node
$ sudo kill -9 PROCESS_ID

参考

https://github.com/jhabdas/react-native-webpack-starter-kit/issues/30#issuecomment-180838137

react プロセスのパターンもあるみたい.

react−nativeの最初につまずいたところメモφ(。_。 ) - Qiita

input type="file" accept で .m4a 形式のファイルをデフォルトの選択対象にする場合は audio/x-m4a を使う

タイトルが本文.

実現したかったこと

<input type="file">

でデフォルトでは .m4a 形式のファイルだけを選択対象にする.

.m4a とは

非圧縮ファイル(WAVやAIFF)を音質の劣化なく70%から50%程圧縮する。通常はQuickTimeのMOVファイル(.mov)かMP4ファイル(.m4a)に格納される。

ロスレスで50%サイズダウンすごい.

試したこと

素直に <input type="file" accept="audio/m4a">

-> 全てのファイル形式が対象になる: ☓

あ, m4a は mp4 ベースの拡張だから <input type="file" accept="audio/mp4">

-> .mp4 が対象になる: ☓

-もう <input type="file" accept="audio/*"> で妥協しよう

-> ☓

結論

<input type="file" accept="audio/x-m4a">

なぞは残る

Media Types

developer.mozilla.org

あたりを探しても関する情報はなく...

help.dottoro.com

に audio/m4a の Aliases として audio/x-m4a があったので試してみたらいけた.

現行の Chrome 63 と Safari 11.0.2 では実現できた.

Web 標準ではないけど各ブラウザが実装している..?

優先度は高くないので, 時間あるときにでも調べていきたい.

React Native で実行対象の Android デバイスを選択してビルドする

blog.morugu.com

↑を乗り越えた後に, emulator を起動しつつリアルデバイスも繋いだ状態で

react-native run-android したところ emulator が優先された.

なので明示的に実行対象を指定する方法.

実行可能な一覧を取得

adb devices で使用可能な( adb サーバに接続された ) emulator/device が表示される.

$ adb devices
List of devices attached
adb server version (39) doesn't match this client (36); killing...
adb E 54586 8413562 usb_osx.cpp:147] Unable to create an interface plug-in (e00002be)
* daemon started successfully *

emulator-xxxx   device
xxxxxyyyyy      device

emulator-xxxx はその名の通りなので, 実機ビルドしたい場合は xxxxxyyyyy の方をコピーしておく.

実行

react-native run-android --deviceId xxxxxyyyyy

--deviceId で対象を指定. 以上!

参考

https://facebook.github.io/react-native/docs/running-on-device.html

http://android.keicode.com/devenv/what-is-adb.php

Redis でワイルドカードを使った複数 key の一括削除

Redis で key_name_* で一致する key を削除したいときに

key に使用している文字列によって最適な方法が違うのでまとめておく.

だいたいは redis-cli コマンドで ok

redis-cli KEYS "key_name_*" | xargs redis-cli DEL

基本的にはこれを使えば問題ない.

クォートを使った文字列の場合

key にクォートが含まれていると xargs が文字列を処理できずエラーになる.

xargs: unmatched single quote; by default quotes are special to xargs unless you use the -0 option

Linux 環境

redis-cli KEYS "key_name_*" | xargs -d '\n' redis-cli DEL
-d オプション について

every character in the input is taken literally.

文字列がそのまま解釈されるようになる.

xargs(1) - Linux manual page

macOS 環境

redis-cli KEYS "key_name_*" | xargs -0 redis-cli DEL

macOS の xargs には -d オプションがない.

xargs(1) Mac OS X Manual Page

その他

Lua

Redis 2.6 以降では EVAL コマンドで Lua Scripting で操作することができ, それを使った方法.

redis-cli EVAL "return redis.call(\'DEL\', unpack(redis.call(\'KEYS\', ARGV[1])))" 0 "key_name_*";

ただし, 1024件以上のデータ量になる場合 too many results to unpack エラーが発生する.

Lua の Default Stack Size が 1024 で定義されているため.

Lua 4.0.1 source code - llimits.h

対策( Feature request, zrevrangebyscore with STORE option · Issue #678 · antirez/redis · GitHub )はあるけど

素直に xargs 使ったほうが良さそう.

参考

Delete redis keys with unmatched single quotes · GitHub