URI::QueryParamのquery_paramよりquery_param_appendを使用した方がいい理由について
URI::QueryParam - Additional query methods for URIs
https://metacpan.org/pod/URI::QueryParam
perlにはURI::QueryParamというモジュールがありまして、URIモジュールだけだと
届かない痒いところに手が届くことをしてくれるモジュールです。
例えば、uriから特定のパラメータだけを削りたいとかそういう場合
URIだけだと面倒なんですが、URI::QueryParamがあれば割と簡単に消せます。
# uri_query.pl use strict; use warnings; use URI; use URI::QueryParam; my $uri = URI->new('http://google.com/'); $uri->query_form( a => 1 ); warn $uri->as_string; $uri->query_param_delete('a'); warn $uri->as_string;
http://google.com/?a=1 at uri_query.pl line 8. http://google.com/ at uri_query.pl line 10.
その逆の追加もよろしくやってくれて
同一パラメータでもちゃんと追加対象にしてくれています。
# uri_query.pl use strict; use warnings; use URI; use URI::QueryParam; my $uri = URI->new('http://google.com/'); $uri->query_form( a => 1 ); warn $uri->as_string; $uri->query_param_append( a => 1 ); warn $uri->as_string;
http://google.com/?a=1 at uri_query.pl line 8. http://google.com/?a=1&a=1 at uri_query.pl line 10.
問題は初期化時にどうすべきか?
ということでして、通常であればこういう感じにしてあげれば
メソッドの利用目的にも合っているのではないかと思うのですが、
# uri_query.pl use strict; use warnings; use URI; use URI::QueryParam; sub add_default_param { my $uri = URI->new(shift); $uri->query_param_append( a => 1 ); $uri->query_param_append( b => 1 ); $uri->as_string; } warn add_uri_param('http://google.com/?hoge=1');
条件
- 渡される引数が想定可能であり、
- なおかつ同一パラメーターが無い
query_paramとどちらをおすすめすべきか?を定量的に返したい。
- 想定できない場合においてはquery_param_appendが正しいはず。
- 一応運用上の問題点を挙げるなら、安易にまねされるケースがあり得るなどがあげられます。
- とりあえずそこを無視した場合にquery_param_appendを推奨するに足る根拠が欲しい。
use strict; use warnings; use Benchmark qw(:all); use URI; use URI::QueryParam; my $count = 100000; timethese($count, { query_param => sub { my $uri = URI->new('http://google.com/'); $uri->query_param( a => 1 ); $uri->query_param( b => 1 ); $uri->query_param( c => 1 ); $uri->query_param( d => 1 ); $uri->query_param( f => 1 ); $uri->as_string; }, query_param_append => sub { my $uri = URI->new('http://google.com/'); $uri->query_param_append( a => 1 ); $uri->query_param_append( b => 1 ); $uri->query_param_append( c => 1 ); $uri->query_param_append( d => 1 ); $uri->query_param_append( f => 1 ); $uri->as_string; }, });
とりあえず、2回ほど試してみた。
Benchmark: timing 100000 iterations of query_param, query_param_append... query_param: 17 wallclock secs (17.43 usr + 0.00 sys = 17.43 CPU) @ 5737.23/s (n=100000) query_param_append: 14 wallclock secs (13.20 usr + 0.00 sys = 13.20 CPU) @ 7575.76/s (n=100000) Benchmark: timing 100000 iterations of query_param, query_param_append... query_param: 19 wallclock secs (18.46 usr + 0.00 sys = 18.46 CPU) @ 5417.12/s (n=100000) query_param_append: 14 wallclock secs (14.27 usr + 0.01 sys = 14.28 CPU) @ 7002.80/s (n=100000)
appendの方が高速のようだ。いったんこの結果が一つの理由になるので𠮷とする。
ただ、内部的にどうなのか追いたいので後日追記します。(短いのである程度は判明してますが)