Kossy::Validator
I released Kossy::Validator to CPAN. It was separated from Kossy
https://metacpan.org/release/Kossy-Validator
You can use Kossy::Validator modules w/o Kossy.
ぜひ毎日通って下さいww RT @mackee_w: Kossy::Validator分離してくだされ〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜って言うために横浜すた丼に通うという話が出てきている
— masahiro nagano (@kazeburo) October 2, 2013
Cache::Memcached::Fast::Safe 0.04 was out. It has get_or_set()
I added get_or_set() to Cache::Memcached::Fast::Safe and released as ver. 0.04
https://metacpan.org/release/Cache-Memcached-Fast-Safe
I saw some people make a module that inherits Cache::Memcached::Fast::Safe only for adding get_or_set().
sample code
use Cache::Memcached::Fast::Safe; my $memd = Cache::Memcached::Fast::Safe->new({ servers => [..] }); $memcached->get_or_set('key:'.$id,sub { MyDB->retrieve($id) },$expires); #or $memcached->get_or_set('key:'.$id,sub { my $val = MyDB->retrieve($id); return ($val, $expires) });
Released Kossy-0.23. Improve Performance
Kossy-0.23 gets 2x or more faster.
https://metacpan.org/release/Kossy
I made these changes.
- Cache Kossy::Request->base. URI->canonical is slow.
- Use Router::Boom for router
- Use HTTP::Headers::Fast
- Optimize Kossy::Response->finalize
Benchmark
#!/usr/bin/env perl use strict; use warnings; package MyApp; use strict; use warnings; use Kossy; get "/" => sub { my ( $self, $c ) = @_; $c->response->body("ok"); }; router [qw/GET POST/] => "/bar" => sub { my ( $self, $c ) = @_; $c->response->body("ok"); }; get "/uri_for" => sub { my ( $self, $c ) = @_; for (1..4) { $c->request->uri_for("/uri_for")->as_string; } $c->response->body( $c->request->uri_for("/uri_for")->as_string ); }; get '/ok' => sub { my ( $self, $c ) = @_; $c->response->body("ok"); }; package main; use HTTP::Request::Common; use HTTP::Message::PSGI; use Plack::Test; use Plack::Builder; use Benchmark qw/cmpthese timethese/; my $env = req_to_psgi(GET "/uri_for"); my $env_ok = req_to_psgi(GET "/ok"); my $app = MyApp->psgi; cmpthese(timethese(0,{ 'kossy_uri_for' => sub { $app->($env); }, 'kossy_ok' => sub { $app->($env_ok); } }));
Kossy 0.20
Benchmark: running kossy_ok, kossy_uri_for for at least 3 CPU seconds... kossy_ok: 3 wallclock secs ( 3.00 usr + 0.01 sys = 3.01 CPU) @ 5860.47/s (n=17640) kossy_uri_for: 3 wallclock secs ( 3.02 usr + 0.02 sys = 3.04 CPU) @ 1647.04/s (n=5007) Rate kossy_uri_for kossy_ok kossy_uri_for 1647/s -- -72% kossy_ok 5860/s 256% --
Kossy 0.23
Benchmark: running kossy_ok, kossy_uri_for for at least 3 CPU seconds... kossy_ok: 4 wallclock secs ( 3.16 usr + 0.00 sys = 3.16 CPU) @ 12560.13/s (n=39690) kossy_uri_for: 4 wallclock secs ( 3.24 usr + 0.00 sys = 3.24 CPU) @ 4211.73/s (n=13646) Rate kossy_uri_for kossy_ok kossy_uri_for 4212/s -- -66% kossy_ok 12560/s 198% --
Plack::Middleware::Session uses Cookie::Baker
Plack::Middleware::Session 0.21 uses Cookie::Baker for improve performance. Cookie::Baker is simple cookie generator/parser module.
https://metacpan.org/release/Plack-Middleware-Session
Previous version of Plack::Middleware::Session uses Plack::Response for only generating cookie strings. By using Cookie::Baker, cookie header setter becomes 600% faster.
benchmark: https://gist.github.com/kazeburo/6896740
Benchmark: running baker, original for at least 1 CPU seconds... baker: 1 wallclock secs ( 1.06 usr + 0.00 sys = 1.06 CPU) @ 95466.98/s (n=101195) original: 1 wallclock secs ( 1.14 usr + 0.00 sys = 1.14 CPU) @ 13472.81/s (n=15359) Rate original baker original 13473/s -- -86% baker 95467/s 609% --
Released Cookie::Baker to CPAN
I released Cookie::Baker that provides HTTP cookie generator and parser
http://search.cpan.org/~kazeburo/Cookie-Baker/
https://metacpan.org/release/Cookie-Baker
### synopsis
use Cookie::Baker; $headers->push_header('Set-Cookie', bake_cookie('foo','val')); my $cookie = bake_cookie('foo', { val => 'val', path => "test", domain => '.example.com', expires => '+24h' }); my $cookies_hashref = crush_cookie($headers->header('Cookie'));
bake_cookie's expires accepts some formats like this.
expires => time + 24 * 60 * 60 # epoch time expires => 'Wed, 03-Nov-2010 20:54:16 GMT' expires => '+30s' # 30 seconds from now expires => '+10m' # ten minutes from now expires => '+1h' # one hour from now expires => '-1d' # yesterday (i.e. "ASAP!") expires => '+3M' # in three months expires => '+10y' # in ten years time expires => 'now' #immediately
I know that cpan has already may cookie related modules. But dead simple cookie generator and parser module to use Plack::Middlewares and Web Applications isn't there.
Monoceros supports accept4(2)
tokuhirom released Linux::Socket::Accept4 that provides accept4(2)
Monoceros-0.25 uses accept4 if Linux::Socket::Accept4 is avaliable.
accept4(2) can set FD_CLOEXEC and O_NONBLOCK in one system call.
Monoceros-0.24
select(16, [4 10], NULL, NULL, {1, 0}) = 1 (in [4], left {0, 999997}) accept(4, {sa_family=AF_INET, sin_port=htons(41296), sin_addr=inet_addr("127.0.0.1")}, [16]) = 6 ioctl(6, SNDCTL_TMR_TIMEBASE or TCGETS, 0x7fffc03016c0) = -1 EINVAL (Invalid argument) lseek(6, 0, SEEK_CUR) = -1 ESPIPE (Illegal seek) ioctl(6, SNDCTL_TMR_TIMEBASE or TCGETS, 0x7fffc03016c0) = -1 EINVAL (Invalid argument) lseek(6, 0, SEEK_CUR) = -1 ESPIPE (Illegal seek) fcntl(6, F_SETFD, FD_CLOEXEC) = 0 fcntl(6, F_SETFL, O_RDONLY|O_NONBLOCK) = 0 setsockopt(6, SOL_TCP, TCP_NODELAY, [1], 4) = 0 read(6, "GET / HTTP/1.0\r\nHost: localhost:"..., 131072) = 82 gettimeofday({1381121587, 895814}, NULL) = 0 write(6, "HTTP/1.1 200 OK\r\nDate: Mon, 07 O"..., 112) = 112 close(6) = 0
Monoceros-0.25
select(16, [4 10], NULL, NULL, {1, 0}) = 1 (in [4], left {0, 999997}) accept4(4, {sa_family=AF_INET, sin_port=htons(42605), sin_addr=inet_addr("127.0.0.1")}, [16], SOCK_CLOEXEC|SOCK_NONBLOCK) = 6 setsockopt(6, SOL_TCP, TCP_NODELAY, [1], 4) = 0 read(6, "GET / HTTP/1.0\r\nHost: localhost:"..., 131072) = 82 gettimeofday({1381121654, 200708}, NULL) = 0 write(6, "HTTP/1.1 200 OK\r\nDate: Mon, 07 O"..., 112) = 112 close(6) = 0
Monoceros-0.25 also skips lseek and ioctl system calls. Perlio layer add these system calls. so I added "use open IO => :unix" before accept().
In my benchmarking, there are no performance effects with accept4. hmmm
ISUCON3 予選に参加してきました。無念ばかり残る
isucon3予選に @sugyan @tagomorisとLINE選抜チームを組んで参加しました。共催枠なので結果に関わらず本戦には出れるのですが、結果は総合8位。無念です
やったこと
sugyanのエントリが詳しいのですが、自分がやったのは
- nginx(openresty)への入れ替え
- mysql 5.5へのダウングレード
- Starlet/Monocerosへの入れ替え
正直5.6とか分からないので5.5で。my.cnfを公開してあるやつから持って来てbinlogを消したりした。おかげで memcached plugin にまったく気付いてなかった。
あれこれ
自分とtagomorisはこれまでの2回とも出題側だったので、参加は今回が初。予選は免除されているのですが、出ておいてよかった。これほど出来る事が少ないのかと驚いた。この短時間でアプリケーションを作り直すのマジ凄い。自分、速くプログラム書くのが苦手なので sugyan がいて助かった
ということで、予選の復習と本戦に向けてのあれこれ作戦をチームで考えて行きたい所存
さいごに
予選・本戦あるの大変だ。 @fujiwara ++。