embulk-filter-calcite vs embulk-filter-column|row の速度比較

[embulk-filter-calcite](https://github.com/muga/embulk-filter-calcite) を使うと任意の SQL を書いてフィルタリングできて圧倒的に便利そうなので、拙作の [embulk-filter-row](https://github.com/sonots/embulk-filter-row) および [embulk-filter-column](https://github.com/sonots/embulk-filter-column) はお役御免にできるかと思って、速度比較をしてみました。

EDIT: (2017/05/19) embulk-filter-calcite 0.1.3 で高速化されたので再計測しました

# tl; dr

embulk-filter-row との比較

| Plugin                        | Operator                             | Time took | records/s   |
|-------------------------------|--------------------------------------|-----------|-------------|
| No Filter                     |                                      | 0m22.283s | 1,996,173/s |
| embulk-filter-row (0.4.0)     | 文字列の = 演算子                     | 0m22.587s | 1,985,173/s |
| embulk-filter-row (0.4.0)     | 文字列の INCLUDE 演算子               | 0m22.720s | 1,950,355/s |
| embulk-filter-row (0.4.0)     | 文字列の REGEXP 演算子                | 0m24.409s | 1,891,768/s |
| embulk-filter-calcite (0.1.3) | 文字列の = 演算子                     | 0m27.169s | 1,848,217/s |
| embulk-filter-calcite (0.1.3) | 文字列の LIKE 演算子                  | 0m31.449s | 1,378,448/s |
| embulk-filter-calcite (0.1.3) | 文字列の SIMILAR TO (REGEXP) 演算子   | 0m30.002s | 1,662,658/s |

embulk-filter-column との比較

| Plugin                        | Operator                             | Time took | records/s   |
|-------------------------------|--------------------------------------|-----------|-------------|
| No Filter                     |                                      | 0m22.283s | 1,996,173/s |
| embulk-filter-column (0.6.0)  | カラムのコピー                        | 0m24.130s | 1,896,178/s | 
| embulk-filter-calcite (0.1.3) | カラムのコピー                        | 0m29.178s | 1,656,780/s |

embulk-filter-row ないしは embulk-filter-column のほうが速いという事実はあるものの、embulk-filter-calcite でも十分実用に耐える速度が出ている(0.1.3 で出るようになった)と判断する。(`LIKE` がちょっと遅いけど)

なお、embulk-filter-calcite の場合に、records/s の比以上に embulk 実行全体の時間がかかっているのは、calcite ライブラリのロードもしくは初期化に多少時間がかかっているためと思われる。2.5 sec ぐらい余分にかかっていそう。JVM起動にかかる時間のほうが遅いので、あまり気にする必要もないかもしれない。

# スペック

## 計測ホストスペック

```
CPU: Intel(R) Xeon(R) CPU X5650  @ 2.67GHz 24コア
Memory: 12GB
```

## テストデータ

手元にあった 1.4GB、2700万行程度の tsv ファイル。内容を少しだけ見せるとこんなかんじ

```test.tsv
27      74813552        30111021        2       1411559797      1411559797      0
28      74813552        30111001        1       1411559797      1411559797      0
29      74813552        30121001        1       1411559797      1411559797      0
30      74813552        30111011        1       1411559797      1411559797      0
39      102516762       30111021        2       1411607973      1411607973      0
40      102516762       30111001        1       1411607973      1411607973      0
```

## ベース設定ファイル

filter プラグインの速度比較をしたいので、一番ベーシックな input file プラグインと、何もパースしないパーサプラグイン [embulk-parser-none](https://github.com/sonots/embulk-parser-none) を使って読み込むようにした。

全体の実行時間だけだと、ライブラリのロードや初期化が大きな割合を占める可能性があるので、embulk-filter-speedometer を使って、records/s も計測するようにした。

設定ファイル

```
in:
  type: file
  path_prefix: 'test.tsv'
  parser:
    type: none
    column_name: payload
filters:
  - type: speedometer
    log_interval_seconds: 1
out:
  type: "null"
```

この時点での結果も time コマンドで計測

```
real    0m22.283s
user    0m39.431s
sys     0m1.332s
```

## 実行コマンド

あえて何もオプションを指定せずに標準のまま実行

```
time embulk run config.yml
```

# 行フィルタリング (WHERE) 比較

## embulk-filter-row の場合

version: 0.4.0

### 文字列の = 演算子

設定ファイル

```
in:
  type: file
  path_prefix: 'test.tsv'
  parser:
    type: none
    column_name: payload
filters:
  - type: speedometer
    log_interval_seconds: 1
  - type: row
    where: payload = '1411559797'
out:
  type: "null"
```

結果

```
real    0m22.587s
user    0m44.078s
sys     0m1.466s
```

### 文字列の INCLUDE 演算子

```
in:
  type: file
  path_prefix: 'test.tsv'
  parser:
    type: none
    column_name: payload
filters:
  - type: speedometer
    log_interval_seconds: 1
  - type: row
    where: payload INCLUDE '1411559797'
out:
  type: "null"
```

結果

```
real    0m22.720s
user    0m43.971s
sys     0m1.274s
```

### 文字列の REGEXP 演算子

設定ファイル

```
in:
  type: file
  path_prefix: 'test.tsv'
  parser:
    type: none
    column_name: payload
filters:
  - type: speedometer
    log_interval_seconds: 1
  - type: row
    where: payload REGEXP '.*1411559797.*'
out:
  type: "null"
```

結果

```
real    0m24.409s
user    0m55.883s
sys     0m1.666s
```

## embulk-filter-calcite の場合

version: 0.1.3

### 文字列の = 演算子

設定ファイル

```
in:
  type: file
  path_prefix: 'test.tsv'
  parser:
    type: none
    column_name: payload
filters:
  - type: speedometer
    log_interval_seconds: 1
  - type: calcite
    query: SELECT payload FROM $PAGES WHERE payload = '1411559797'
out:
  type: "null"
```

結果

```
real    0m27.169s
```

### 文字列の LIKE 演算子

設定ファイル

```
in:
  type: file
  path_prefix: 'test.tsv'
  parser:
    type: none
    column_name: payload
filters:
  - type: speedometer
    log_interval_seconds: 1
  - type: calcite
    query: SELECT payload FROM $PAGES WHERE payload LIKE '%1411559797%'
out:
  type: "null"
```

結果

```
real    0m31.449s
```

### 文字列の SIMILAR TO (REGEXP) 演算子

設定ファイル

```
in:
  type: file
  path_prefix: 'test.tsv'
  parser:
    type: none
    column_name: payload
filters:
  - type: speedometer
    log_interval_seconds: 1
  - type: calcite
    query: SELECT payload FROM $PAGES WHERE payload SIMILAR TO '.*1411559797.*'
out:
  type: "null"
```

結果

```
real    0m30.002s
```

# 列フィルタリング

## embulk-filter-column の場合

version: 0.6.0

### カラムのコピー

設定ファイル

```
in:
  type: file
  path_prefix: 'test.tsv'
  parser:
    type: none
    column_name: payload
filters:
  - type: speedometer
    log_interval_seconds: 1
  - type: column
    columns:
     - { name: payload }
     - { name: copy, src: payload }
out:
  type: "null"
```

結果

```
real    0m24.130s
user    1m4.415s
sys     0m1.770s
```

## embulk-filter-calcite の場合

version: 0.1.3

### カラムのコピー

設定ファイル

```
in:
  type: file
  path_prefix: 'test.tsv'
  parser:
    type: none
    column_name: payload
filters:
  - type: speedometer
    log_interval_seconds: 1
  - type: calcite
    query: SELECT payload,payload as copy FROM $PAGES
out:
  type: "null"
```

結果

```
real    0m29.178s
```