PerlのYAMLライブラリ性能比較
なんと2018年の記事です.皆様無事明けられておりますでしょうか.
さてYAML::XSには2017年に色々と変更が入り,実用するにあたり非常に便利な機能が色々と導入されました (具体的に言うと,$YAML::XS::LoadBlessedと$YAML::XS::Booleanです).また安定化が図られました *1.
というわけで個人的に,最近PerlでYAMLをserialize/deserializeするにあたってはYAML::XSを使うことが多くなってきたわけですが,そこでふと各YAMLライブラリの性能について気になったのでベンチマークを取ってみたという次第です.以下はその記録です.
ベンチマークコード
#!/usr/bin/env perl use strict; use warnings; use utf8; use Benchmark qw(cmpthese); use YAML (); use YAML::Tiny (); use YAML::Syck (); use YAML::XS (); use YAML::PP::Loader; use YAML::PP::Dumper; my $yaml_text = do { local $/; <DATA> }; my $yaml_pp_loader = YAML::PP::Loader->new; # Deserialize cmpthese(10000, { 'YAML' => sub { YAML::Load($yaml_text); }, 'YAML::Tiny' => sub { YAML::Tiny::Load($yaml_text); }, 'YAML::Syck' => sub { YAML::Syck::Load($yaml_text); }, 'YAML::XS' => sub { YAML::XS::Load($yaml_text); }, 'YAML::PP' => sub { $yaml_pp_loader->load_string($yaml_text); }, }); my $hashref = YAML::XS::Load($yaml_text); my $yaml_pp_dumper = YAML::PP::Dumper->new; # Serialize cmpthese(10000, { 'YAML' => sub { YAML::Dump($hashref); }, 'YAML::Tiny' => sub { YAML::Tiny::Dump($hashref); }, 'YAML::Syck' => sub { YAML::Syck::Dump($hashref); }, 'YAML::XS' => sub { YAML::XS::Dump($hashref); }, 'YAML::PP' => sub { $yaml_pp_dumper->dump_string($hashref); }, }); __DATA__ # From: https://github.com/kubernetes/kubernetes/blob/7bbab6234f99af9adb700ff30968794084b6ee12/examples/mysql-wordpress-pd/wordpress-deployment.yaml apiVersion: extensions/v1beta1 kind: Deployment metadata: name: wordpress labels: app: wordpress spec: strategy: type: Recreate template: metadata: labels: app: wordpress tier: frontend spec: containers: - image: wordpress:4.8.0-apache name: wordpress env: - name: WORDPRESS_DB_HOST value: wordpress-mysql - name: WORDPRESS_DB_PASSWORD valueFrom: secretKeyRef: name: mysql-pass key: password.txt ports: - containerPort: 80 name: wordpress volumeMounts: - name: wordpress-persistent-storage mountPath: /var/www/html volumes: - name: wordpress-persistent-storage persistentVolumeClaim: claimName: wp-pv-claim
Deserialize結果
Rate YAML::PP YAML YAML::Tiny YAML::Syck YAML::XS YAML::PP 251/s -- -29% -86% -97% -98% YAML 351/s 40% -- -80% -96% -97% YAML::Tiny 1767/s 604% 403% -- -81% -87% YAML::Syck 9524/s 3696% 2613% 439% -- -30% YAML::XS 13699/s 5360% 3803% 675% 44% --
Serialize結果
Rate YAML YAML::PP YAML::Tiny YAML::XS YAML::Syck YAML 588/s -- -74% -84% -96% -97% YAML::PP 2299/s 291% -- -38% -84% -87% YAML::Tiny 3731/s 535% 62% -- -74% -79% YAML::XS 14286/s 2330% 521% 283% -- -19% YAML::Syck 17544/s 2884% 663% 370% 23% --
なるほどという結果です.
DeserializeはYAML::XSが最も速く,SerializeはYAML::Syckが高速という結果になりました.
もちろん対象とするYAMLのデータ構造に依存する結果ではありますが,性能を考えるのであればYAML::XSかYAML::Syckを使っておけば良さそうという感じですね.
それぞれ,
YAML
: Pure Perl実装.これでしか解釈できない記法が(なぜか!)ある.YAML::Tiny
: Pure Perl実装.PPなのでシンプル.YAML::Syck
: libsyckのバインディング.XSで比較的高速.*2YAML::XS
: libyamlのバインディング.XSで比較的高速.libyamlという安心感がある.現代では安定している.YAML::PP
: Pure Perl実装.YAML 1.2をサポートするというモチベーションらしい.
という特徴があるので (そして各々のライブラリで解釈できる構文が異なる場合があり,これは業界ではヤムルの地獄と呼ばれています),状況に応じて使い分ける必要はありそうです.こちらからは以上です.
まあなんかなんやかやYAML::Tiny使うことは多いです
— はいじゃないが (@moznion) 2018年1月17日
実装がわかりやすいし……
— はいじゃないが (@moznion) 2018年1月17日