rackspace cloudが安い
海外の安いVPSというエントリでLinodeというVPSを紹介したのですが、(条件次第では)それよりもさらに安いrackspace cloudというサービスを見つけました。
プランのスペックが微妙に違うし、データ転送量の料金次第な面もあるので一概に比較出来ませんが、Linodeの540とrackspaceの512MBのプランだとrackspaceの方が7$ぐらいお得。データ転送量が少なければrackspaceも全然ありだなぁ。
海外の安いVPSというエントリでLinodeというVPSを紹介したのですが、(条件次第では)それよりもさらに安いrackspace cloudというサービスを見つけました。
プランのスペックが微妙に違うし、データ転送量の料金次第な面もあるので一概に比較出来ませんが、Linodeの540とrackspaceの512MBのプランだとrackspaceの方が7$ぐらいお得。データ転送量が少なければrackspaceも全然ありだなぁ。
今年のYAPC(9月)からすき間時間を使って作っていたDBIx::Thinという、DBIx::Skinnyインスパイアなモジュールを昨日やっとリリースしました。作った動機は単に自己満足の追求と車輪の再発明による個人のスキルアップですが、前職で3年前ぐらいに自作したORMのコードを忘れないうちに改良して世に出したいなぁとずっと思っていたのです。SkinnyのAdvent Calendarが日々更新されているのを読み、途中で何度も「これSkinny使えばいいんじゃね?」って思って挫折しかけましたが、Skinnyも細かいところでは自分のポリシーと合わない部分があったりしたのと、とりあえず作ってしまったので世に出してみます。
特徴としては
かなと思います。SQLはなんだかんだ言ってもまだWebエンジニアの共通言語だと思うので、ORMでゴリゴリJOINのコードを書くより生SQLの方がわかりやすい、と思っているので、生SQLなモジュールを作りました。
「Skinnyより書き方は冗長」というのは、例えばSkinnyだと
my $iterator = Your::Model->search( 'user', {id => 1}, {order_by => 'id'} );
と書きますが、2つ目の引数が何を表しているのかぱっと見わからないので、Thinの場合は
my $iterator = Your::Model->search( 'user', where => {id => 1}, # これ order_by => 'id', );
と書くようにしています。もちろんSkinnyも学習すれば全然わかると思うので、細かいどうでもいいことかもしれませんが…
あとSkinnyと違う点は、
ところぐらいでしょうか。
最後に、Skinnyのコードはすごく綺麗で色々な部分を参考にさせてもらいました。作者のnekokakさん、どうもありがとうございました。
タイトル通りなんですが、今までは複数のテーブルを削除する時は
> drop table hoge; > drop table fuga;
なんてやってましたが、
> drop table hoge fuga;って書けるんですね。豆知識。
最近Gitの共有リポジトリを構築する機会があったのですが、以下のような感じで運用しています。
いちいちサーバ側にユーザ追加して、gitリポジトリのディレクトリにパーミッション付与するよりこっちの方がたぶん楽。
Perlで日付関連の処理をする代表的なモジュールにDateTimeというものがありますが、メモリ消費量が激しいのがずっと気になっていました。でで、Time::Pieceが5.10.1からPerlに標準添付になったという話を聞いて、乗り換えようかどうか検討しています。Perlメモ/Time::Pieceモジュール – Walrus, Digit.を見ると、DateTimeでできることは大体できるので、以下のユースケースでの速度面を測ってみます。
環境は以下で、ベンチマークのスクリプトは最後に載せてあります。
こちらのgtop.plを使って測ります。
$ gtop.pl 'use DateTime'
10.2M : use DateTime$ gtop.pl 'use Time::Piece'
2.5M : use Time::Pieceおおお、なんと4分の1!
$ ./benchmark_datetime.pl now Benchmark: running now_datetime, now_time_piece for at least 3 CPU seconds... now_datetime: 4 wallclock secs ( 3.03 usr + 0.00 sys = 3.03 CPU) @ 3149.83/s (n=9544) now_time_piece: 2 wallclock secs ( 2.58 usr + 0.53 sys = 3.11 CPU) @ 52694.86/s (n=163881) Rate now_datetime now_time_piece now_datetime 3150/s -- -94% now_time_piece 52695/s 1573% --
15倍!
$ ./benchmark_datetime.pl add Benchmark: running add_datetime, add_time_piece for at least 3 CPU seconds... add_datetime: 3 wallclock secs ( 3.05 usr + 0.00 sys = 3.05 CPU) @ 1853.44/s (n=5653) add_time_piece: 3 wallclock secs ( 2.76 usr + 0.42 sys = 3.18 CPU) @ 54969.81/s (n=174804) Rate add_datetime add_time_piece add_datetime 1853/s -- -97% add_time_piece 54970/s 2866% --
Time::Pieceの圧倒的勝利。28倍!
$ ./benchmark_datetime.pl subtract Benchmark: running subtract_datetime, subtract_time_piece for at least 3 CPU seconds... subtract_datetime: 3 wallclock secs ( 3.00 usr + 0.00 sys = 3.00 CPU) @ 4065.00/s (n=12195) subtract_time_piece: 4 wallclock secs ( 3.15 usr + 0.00 sys = 3.15 CPU) @ 132329.84/s (n=416839) Rate subtract_datetime subtract_time_piece subtract_datetime 4065/s -- -97% subtract_time_piece 132330/s 3155% --
引き算もTime::Pieceの方が圧倒的に速いですね。
$ ./benchmark_datetime.pl compare Benchmark: running compare_datetime, compare_time_piece for at least 3 CPU seconds... compare_datetime: 3 wallclock secs ( 3.04 usr + 0.00 sys = 3.04 CPU) @ 47709.21/s (n=145036) compare_time_piece: 4 wallclock secs ( 3.09 usr + -0.01 sys = 3.08 CPU) @ 173623.70/s (n=534761) Rate compare_datetime compare_time_piece compare_datetime 47709/s -- -73% compare_time_piece 173624/s 264% --
$ ./benchmark_datetime.pl stringify Benchmark: running stringify_datetime, stringify_time_piece for at least 3 CPU seconds... stringify_datetime: 3 wallclock secs ( 3.00 usr + 0.00 sys = 3.00 CPU) @ 44470.33/s (n=133411) stringify_time_piece: 3 wallclock secs ( 2.45 usr + 0.66 sys = 3.11 CPU) @ 116681.35/s (n=362879) Rate stringify_datetime stringify_time_piece stringify_datetime 44470/s -- -62% stringify_time_piece 116681/s 162% --
総じてDateTimeよりTime::Pieceの方が高い性能を叩き出しました。速度にシビアな状況ではTime::Pieceを使った方が良いと感じました。こういう罠もあるみたいなので気をつけなくてはいけないところもありますが… インタフェースはどちらも綺麗に出来ているので使い勝手としては同じぐらいかなと思います。それにしてももっと速くTime::Pieceを検証しておけばよかったと思う今日この頃です。
#!/usr/bin/env perl use strict; use warnings; use Benchmark qw(cmpthese timethese); use DateTime; use Time::Piece; use Time::Seconds; my $timezone = DateTime::TimeZone->new(name => 'local'); #----------------------# # now #----------------------# sub now_datetime { my $now = DateTime->now(time_zone => $timezone); } sub now_time_piece { my $now = localtime; } #----------------------# # add #----------------------# my $add_dt = DateTime->now(time_zone => $timezone); sub add_datetime { $add_dt->add(days => 1); } my $add_tp = localtime; sub add_time_piece { $add_tp += ONE_DAY; } #----------------------# # subtract #----------------------# my $sub_dt1 = DateTime->now(time_zone => $timezone); my $sub_dt2 = DateTime->new( year => 2008, month => 12, day => 1, ); sub subtract_datetime { my $dur = $sub_dt1->subtract_datetime($sub_dt2); } my $sub_tp1 = localtime; my $sub_tp2 = Time::Piece->strptime('2008-12-01', '%Y-%m-%d'); sub subtract_time_piece { my $sec = $sub_tp1 - $sub_tp2; } #----------------------# # compare #----------------------# my $compare_dt1 = DateTime->now(time_zone => $timezone); my $compare_dt2 = DateTime->now(time_zone => $timezone); sub compare_datetime { my $result = DateTime->compare($compare_dt1, $compare_dt2) <= 0; } my $compare_tp1 = localtime; my $compare_tp2 = localtime; sub compare_time_piece { my $result = $compare_tp1 <= $compare_tp2; } #----------------------# # stringify #----------------------# my $now_dt = DateTime->now(time_zone => $timezone); sub stringify_datetime { $now_dt->strftime("%Y-%m-%d"); } my $now_tp = localtime; sub stringify_time_piece { $now_tp->strftime("%Y-%m-%d"); } #----------------------# # main #----------------------# my $mode = shift @ARGV || 'now'; my $count = shift @ARGV || -3; if ($mode eq 'now') { cmpthese timethese $count, { 'now_datetime' => \&now_datetime, 'now_time_piece' => \&now_time_piece, }; } elsif ($mode eq 'add') { cmpthese timethese $count, { 'add_datetime' => \&add_datetime, 'add_time_piece' => \&add_time_piece, }; } elsif ($mode eq 'subtract') { cmpthese timethese $count, { 'subtract_datetime' => \&subtract_datetime, 'subtract_time_piece' => \&subtract_time_piece, }; } elsif ($mode eq 'compare') { cmpthese timethese $count, { 'compare_datetime' => \&compare_datetime, 'compare_time_piece' => \&compare_time_piece, }; } elsif ($mode eq 'stringify') { cmpthese timethese $count, { 'stringify_datetime' => \&stringify_datetime, 'stringify_time_piece' => \&stringify_time_piece, }; }
Now Text::MicroTemplate is even faster than HTML::Template::Pro – use GFx::WebLog;
Text::MicroTemplate 0.10で動作速度が改善されたとのことなので、自分のところでもベンチマークしてみました。
$ perl benchmark_templates.pl 1 Perl/5.10.0 (x86_64-linux-gnu-thread-multi) HTML::Template/2.9 HTML::Template::Compiled/0.94 HTML::Template::Pro/0.92 Template/2.20 Text::MicroTemplate/0.10 Benchmark: running HT, HT::C, HT::Pro, MT, TT for at least 1 CPU seconds... HT: 1 wallclock secs ( 1.03 usr + 0.00 sys = 1.03 CPU) @ 1094.17/s (n=1127) HT::C: 1 wallclock secs ( 1.03 usr + 0.00 sys = 1.03 CPU) @ 11598.06/s (n=11946) HT::Pro: 2 wallclock secs ( 0.82 usr + 0.29 sys = 1.11 CPU) @ 17611.71/s (n=19549) MT: 1 wallclock secs ( 0.96 usr + 0.08 sys = 1.04 CPU) @ 15904.81/s (n=16541) TT: 1 wallclock secs ( 1.08 usr + 0.00 sys = 1.08 CPU) @ 7110.19/s (n=7679) Rate HT TT HT::C MT HT::Pro HT 1094/s -- -85% -91% -93% -94% TT 7110/s 550% -- -39% -55% -60% HT::C 11598/s 960% 63% -- -27% -34% MT 15905/s 1354% 124% 37% -- -10% HT::Pro 17612/s 1510% 148% 52% 11% --
何回かやったのですが、自分の環境ではまだHTML::Template::Proが速いみたい。でも僅差なのでまったく気にならないレベルですね。とにかくgfxさん++すぎる。
PerlでWebアプリを作る時のテンプレートエンジンをどれにしようか相変わらず模索中なのですが、以下の2つのエントリーで動作速度とメモリについて調べた結果、どうやらText::MicroTemplateとHTML::Template::Proのどちらかを選択するのが良いだろうと思っています。
「<TMPL_IF>、<TMPL_LOOP>で改行のコントロールが難しい」というのは、例えば以下のテンプレートファイルがあって、それを実際に出力した時のHTMLに改行が入ってしまう、ということです。
テンプレートファイル
<html> <head></head> <body> <TMPL_IF NAME=hoge> hoge </TMPL_IF> </body> </html>
出力されるHTML
<html> <head></head> <body> #ここに改行 hoge #ここにも改行 </body> </html>
出力するのがHTMLであればそんなに問題はないのですが、メールの文面をテンプレートエンジンで動的に生成したい場合、改行が実直に反映されてしまうので、いつもどうしようか悩んでしまいます。この改行のためにHTMLの生成とメールの生成で別々のテンプレートエンジン使うのも微妙ですし。
もしかするとHTML::Template::Proの filter 機能でなんとかできるのかもしれませんが、まだそこまでは考えられてないです。というわけで相変わらずテンプレートエンジンどうしようか悩み中…
コメント