1
0

【Bun】先日試したベンチのどの行が速いのか確かめて、最後に少し驚いた。

Last updated at Posted at 2023-12-04

先日試したこのベンチのどの行が速いのかちょっと確かめてみたくなった。

このコードは「郵便局の郵便番号データ 18M のcsv(124,332行) を for で回しながら行数カウントするだけのスクリプト」です。やってることはそれほど多くないので、上から順番にベンチを試してみたいと思います。

ただ、今回は Bun と Node.js を完全に区別するべく、node_modules の無いBun用と node_modules の有る Node.js 用のふたつのディレクトリを作って試してみようと思います。

今回の環境

クラウド: Azure VM (これはオンプレでも何でも良い)
OS: Ubuntu 20.04.6 LTS (GNU/Linux 5.15.0-1050-azure x86_64)
Bun: 1.0.15 ( https://bun.sh/blog )
Node.js: v20.9.0

準備

共通の作業

bun用ディレクトリを作って入り read.js を作成する
$ mkdir read-zip-csv_bun
$ cd read-zip-csv_bun

# 郵便番号データをコピーする
$ cp <ファイルへのパス>/zip.csv ./

# 下記の共通read.jsを書く
$ vi read.js

Node.js用ディレクトリを作って入り read.js を作成する
$ mkdir read-zip-csv_node
$ cd read-zip-csv_node

# 郵便番号データをコピーする
$ cp <ファイルへのパス>/zip.csv ./

# 下記の共通read.jsを書く
$ vi read.js
共通のread.js
console.time('csv read'); // 計測開始
const fs = require('fs');

let path='./zip.csv';

const csv =  fs.readFileSync(path, 'utf8');
const oj=csv.split('\n')
let count=0;

for(let i=0; i<oj.length;i++){
    let line=oj[i].split(',')
    count++;
}
console.log(count);
console.timeEnd('csv read'); // 計測終了

生成されたツリー

./read-zip-csv_bun/
    ├─read.js
    └─zip.csv

./read-zip-csv_node/
    ├─read.js
    └─zip.csv

bun用ディレクトリでの作業

at ./read-zip-csv_bun

bun用ディレクトリで read.js を実行する
$ bun read.js
124332
[124.22ms] csv read

noden用ディレクトリでの作業

at ./read-zip-csv_node

bun用ディレクトリで read.js を実行する
$ node read.js
124332
csv read: 290.21ms

ここから順にやっていきます

a-1.js requireだけ
console.time('csv read'); // 計測開始
const fs = require('fs');
console.timeEnd('csv read'); // 計測終了
結果
bun a-1.js
[12.05ms] csv read

$ node a-1.js
csv read: 3.343ms

a-1.js
require('fs')
bun: 12.05ms
node: 3.343ms ◎の勝ち

a-2.js readFileSyncまで
console.time('csv read'); // 計測開始
const fs = require('fs');
let path='./zip.csv';
const csv =  fs.readFileSync(path, 'utf8');
console.timeEnd('csv read'); // 計測終了
結果
$ bun a-2.js
[41.19ms] csv read

$ node a-2.js
csv read: 137.513ms

a-1.jsとa-2.jsの差分
fs.readFileSync
bun: 29.14ms ◎bunの勝ち
node: 134.17ms

a-3.js splitまで
console.time('csv read'); // 計測開始
const fs = require('fs');
let path='./zip.csv';
const csv =  fs.readFileSync(path, 'utf8');
const oj=csv.split('\n')
console.timeEnd('csv read'); // 計測終了
結果
$ bun a-3.js
[51.03ms] csv read

$ node a-3.js
csv read: 165.209ms

a-2.jsとa-3.jsの差分
.split
bun: 9.84ms ◎bunの勝ち
node: 27.696ms

a-4.js forまで
console.time('csv read'); // 計測開始
const fs = require('fs');
let path='./zip.csv';
const csv =  fs.readFileSync(path, 'utf8');
const oj=csv.split('\n')
let count=0;
for(let i=0; i<oj.length;i++){
    let line=oj[i].split(',')
    count++;
}
console.timeEnd('csv read'); // 計測終了
結果
$ bun a-4.js
[122.76ms] csv read

$ node a-4.js
csv read: 285.202ms

a-3.jsとa-4.jsの差分
for
bun: 71.73ms ◎bunの勝ち
node: 119.993ms

a-5.js console.log(count)まで
console.time('csv read'); // 計測開始
const fs = require('fs');
let path='./zip.csv';
const csv =  fs.readFileSync(path, 'utf8');
const oj=csv.split('\n')
let count=0;
for(let i=0; i<oj.length;i++){
    let line=oj[i].split(',')
    count++;
}
console.log(count);
console.timeEnd('csv read'); // 計測終了
結果
$ bun a-5.js
124332
[123.30ms] csv read

$ node a-5.js
124332
csv read: 289.192ms

a-4.jsとa-5.jsの差分
console.log
bun: 0.54ms ◎bunの勝ち
node: 3.99ms

まとめ

require('fs')の読み込み以外は Bun の勝ちだった。全体通してはa-5.jsでみたとおりほぼ 2.3倍の差がついた。

require('fs')は、Node.jsもビルトインモジュールなので速いのだろうか。これを importにしたらどうなるのかと思い、これだけ試してみた。

b-1.js Bun用
console.time('csv read'); // 計測開始
import fs from 'fs'; //import分に変えてみる
console.timeEnd('csv read'); // 計測終了
b-1.mjs Node.js用
console.time('csv read'); // 計測開始
import fs from 'fs'; //import分に変えてみる
console.timeEnd('csv read'); // 計測終了
結果
$ bun b-1.js
[0.00ms] csv read

$ node b-1.mjs
csv read: 0.088ms

うひゃぁ。Bunの0.00msてなんだよっfrq;えおjkくぇおj

し、失礼いたしました。

それでは、最後に require を import に変えた全体で試してみましょう。

b-5.js または b-5.mjs
console.time('csv read'); // 計測開始
import fs from 'fs';

let path='./zip.csv';

const csv =  fs.readFileSync(path, 'utf8');
const oj=csv.split('\n')
let count=0;

for(let i=0; i<oj.length;i++){
    let line=oj[i].split(',')
    count++;
}
console.log(count);
console.timeEnd('csv read'); // 計測終了
結果
n$ bun  b-5.js
124332
[110.25ms] csv read

$ node b-5.mjs
124332
csv read: 286.079ms

まぁ、やはりBun の勝ちでござるな。

あと、Bun は、require より import を使う方が幸せかも?少なくとも fs は。

最近 Qiita に書いた Bun 関連の記事10選

1
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
1
0