PostgreSQLには今の日付を入れるcurrent_dateなんてものがあることを今更知った。
今まではPerlでTime::Pieceとかを使って先に日付を用意して、SQL文に入れてたんだけど、どっちが速いのか気になったので計測してみた。
注意(2010/10/19追記)
id:perlcodesampleさんの指摘で計測による結論が正確ではないと分かったのでこのエントリは参考にしないで下さい。
とりあえず環境。Ubuntu10.10(i386)とそこそこ新しいPC。
PerlとPostgeSQLはapt-getを使って入れた。
Polaroidoon@ubuntu:~/perltest$ perl -v This is perl, v5.10.1 (*) built for i686-linux-gnu-thread-multi (with 40 registered patches, see perl -V for more detail) Copyright 1987-2009, Larry Wall Perl may be copied only under the terms of either the Artistic License or the GNU General Public License, which may be found in the Perl 5 source kit. Complete documentation for Perl, including FAQ lists, should be found on this system using "man perl" or "perldoc perl". If you have access to the Internet, point your browser at http://www.perl.org/, the Perl Home Page. Polaroidoon@ubuntu:~/perltest$ psql --version psql (PostgreSQL) 8.4.5 contains support for command-line editing
んで、テーブル。
test=> \d datebench Table "public.datebench" Column | Type | Modifiers --------+------------------------+----------- date | date | not null time | time without time zone | not null
あとはテストに使ったプログラム。
#!/usr/bin/perl use warnings; use strict; use Benchmark qw/timethese cmpthese/; use DBIx::Simple; use Time::Piece; my @dsn = ( 'dbi:Pg:host=localhost;database=test;', 'username', 'password', {RaiseError => 1}, ); my $t; my $db = DBIx::Simple->connect(@dsn) or die DBIx::Simple->error; my $result = timethese(10000, { name1 => sub { $t = Time::Piece::localtime(); $db->query( 'INSERT INTO datebench (date,time) VALUES (?, ?);', $t->ymd, $t->hms); }, name2 => sub { $db->query( 'INSERT INTO datebench (date,time) VALUES (current_date, current_time);' ); }, }); cmpthese($result);
CPANのBenckmarkモジュールを使って1万回実行した結果で測定。
Benckmarkでの結果にはIO待ちの時間が出なくてCPU時間だけが出るらしいんだけど、まぁ、テーブルに書き込む内容は同じようなモンでしょ。と逃げる。
そして、実行結果がこれ。
Polaroidoon@ubuntu:~/perltest$ perl test.pl Benchmark: timing 10000 iterations of name1, name2... name1: 85 wallclock secs ( 4.84 usr + 0.78 sys = 5.62 CPU) @ 1779.36/s (n=10000) name2: 84 wallclock secs ( 1.73 usr + 0.22 sys = 1.95 CPU) @ 5128.21/s (n=10000) Rate name1 name2 name1 1779/s -- -65% name2 5128/s 188% --
name1がTime::Piece。
name2がPostgeSQLまかせ。
ということでSQL文で用意した方がいいみたい。(2010/10/19削除)
次からこっちにしよう。
追記(2010/10/19追記)
perlcodesampleさんに教えていただいたwallclock secsで比較すると85secと84sec。
ということはほぼ一緒だなぁ。DBとPerlのCPU使用率とかもっと他のものまで見ないと比較は難しそうだ。
Benckmark参考:
http://d.hatena.ne.jp/perlcodesample/20100509/1276960096