Test::Synchronized released

2009-12-09 01:26

Tim Bray wrote on his article Concur.next that:

No longer; Next year’s system will do more computing all right, but by giving you more CPUs, running at this year’s speed, to work with.

Perl’s multi-core support is good old-fashioned fork(2). It’s not sexy, but it works. So recently I began to use “prove -j9″. But some of our project’s tests are not works correctly under the “prove” command.

For example, our cron script has tests that create and remove a log file.

  • foo.t open and create a log file.
  • foo.t write something to the file.
  • foo.t remove the file.
  • bar.t open and create a new log file.
  • bar.t write something to the file.
  • bar.t remove the file.

And it’s not works at the same time.

  • foo.t open and create a log file.
  • bar.t open the log file.
  • foo.t write something to the file.
  • bar.t write something to the file, too.
  • foo.t remove the file.
  • bar.t can’t remove the file.

I can modify the code to fix it. However, I’m lazy and impatient. So I wrote a simple lock system named Test::Synchronized.

Test::Synchronized provides a giant lock to your tests. When you add “use Test::Synchronized;” on both foo.t and bar.t.

  • foo.t create a lock directory.
  • foo.t open and create a log file.
  • bar.t can’t create the lock directory. So bar.t wait the end of foo.t.
  • foo.t write something to the file.
  • foo.t remove the file.
  • foo.t remove the lock directory.
  • bar.t create a new lock directory.
  • bar.t open and create a new log file.

It’s not sexy, but it works :)

I released 0.01 on Bitbucket and CPAN already. Enjoy!

0.02

Tokuhiro-san (aka tokuhirom) blogged about some bugs and problems of Test::Synchronized. So I fixed and released 0.02 now. Thanks a lot.

11月をふりかえる

2009-11-26 22:09

11月は早かった。さっきはじまったような気がする。ぼんやりしている間に25歳になっていて、しかし25歳らしいことをしているかといわれると、目もあてられない。

私はなにがしたいんだろうなあ。

行ったライブ: Easel presents「neco眠る vs あらかじめ決められた恋人たちへ」(渋谷 O-Nest)

すごく混んでいた。前半は neco 眠るで、後半があら恋。neco 眠るはぜんぜんノイズよりでなく、楽しくて良かったので思わず CD まで買ってしまった。新しいひとの CD 買うのは久しぶり。あら恋はあいかわらずかっこよかった。

出た飲み会: chromiumExtensionDevCon

Google Chrome / Chromium をネタにした飲み会。Twitter ユーザー中心っぽかったけど気にせずまざる。Chrome (PNG と pixel で一致をみるテストはだめだ / タイルなウィンドウマネージャつかってるから Glen ボタンみえない / w3m + WebKit / …) から関係ないこと (X は悪くない / Scala はコンパイルが遅い / …) まで、いろいろ話せて楽しかった。元同僚とも会ったので二次会はスタバ。

出展したイベント: Make: Tokyo Meeting 04

これについてはいろいろ書くことがあるので後で。

Subversion のワーキングコピー上の File::Find を速くする

2009-11-16 03:13

Perl の File::Find で簡単な、たとえば JavaScript のファイルを列挙する処理を書いたとする。

find(sub { print "$File::Find::name\n" if m/\.js$/; }, '.');

いつもこんな風にすませていたんだけど、これを Subversion レポジトリのワーキングコピー上で走らせると普通より遅い。ワーキングコピー上のすべてのフォルダには .svn という Subversion のメタデータを保存するフォルダがあり、そもそもたどるべき木が大きいので当たり前だ。

たとえば Google Closure Library の場合 svn checkout したものが150MB, svn export したものが69MBになる。

各地の .svn 以下の部分木を無視すればいいので、いつか枝刈りつきの File::Find を書くか探すかしようとしていたんだけど、preprocess オプションをつけるとそれができることがわかった。

find({
     wanted => sub {
        print "$File::Find::name\n" if m/\.js$/;
    },
    preprocess => sub {
        grep { $_ ne '.svn' } @_;
    },
    '.'
);

ベンチマークをとったらちゃんと速くなっていた。数字 (4倍) はレポジトリに左右されると思う。

% svn info
Path: .
URL: http://closure-library.googlecode.com/svn/trunk
Repository Root: http://closure-library.googlecode.com/svn
Repository UUID: 0b95b8e8-c90f-11de-9d4f-f947ee5921c8
Revision: 8
Node Kind: directory
Schedule: normal
Last Changed Author: dtbentley
Last Changed Rev: 8
Last Changed Date: 2009-11-13 13:51:43 +0900 (金, 13 11 2009)

% perl ~/find.pl
...
             Rate      plain preprocess
plain      5.94/s         --       -71%
preprocess 20.4/s       243%         --
%

ベンチマークに使った find.pl はこんな感じです。

use strict;
use warnings;
use File::Find;
use Benchmark;

sub print_if_javascript {
    print "$File::Find::name\n" if m/\.js$/;
}

Benchmark::cmpthese(-1, {
    preprocess => sub {
        find({
            wanted => \&print_if_javascript,
            preprocess => sub {
                grep { $_ ne '.svn' } @_;
            }
        }, '.');
    },

    plain => sub {
        find({
            wanted => \&print_if_javascript,
        }, '.');
    }
});

速くなるのは当たり前だけど、予想より簡単だったのがうれしかった。