Hatena::ブログ(Diary)

Islands in the byte stream

2013-06-11

Safari on iOS7のv8bench

v8bench version 7

iOS6のSafariは681、UIWebViewは113でした: v8bench scores for smartphones - Islands in the byte stream

同じ端末でiOS7にアップグレードして測定したところ、Safariのスコアが1.5倍ほどに上がっていることを観察しました。

UIWebViewの値が伸びていないことから、JITの性能だけが上がったと考えられます。

2013-06-02

Xslateで多重にWRAPPERを使っているケースで起きる問題

表題の問題を修正した 2.0005 をリリースしました。以前からWRAPPERを使っている場合に稀に起きることはわかっていたものの、再現できずに困っていたのでした。TTerseのWRAPPERのみならず、Kolonのtemplate cascadingでも同様の問題が起きる可能性がありますので、アップグレードするのをおすすめします。

2013-05-23

overloadプラグマの使い方

404 Blog Not Found:紹介 - Software Design 2013年06月号

呼ばれてないけど勝手に添削。

use overload
  '""' => 'toString',
  '_'  => 'add',
;

はないわー。そこは

use overload
  '""' => \&toString,
  '_'  => \&add,
;

でしょうが。

いいえ、overloadプラグマの引数は文字列でいいんです。でないとサブクラスでオーバーライドできませんから。

つまり、overloadプラグマへ与えるメソッドの実体$methodは、$obj->$method()として与えられたかのように振舞うのです。コードリファレンスを与えると、メソッドのレシーバが何であろうとそのコードリファレンスが呼び出されてしまいます。文字列であれば、サブクラスでたとえばtoString()メソッドをオーバーライドしたときに正しくそのサブクラスのtoString()メソッドが呼び出されます。オーバーライドしたメソッドを適切に呼び出すということであれば'""' => sub { shift()->toString() }でもかまいませんが、ぼくは文字列で指定するほうが簡潔なので好きです。

以下検証コード:

#!perl
use 5.14.0;
use strict;
use warnings;

package ByStr {
    use overload '""' => 'toString';

    sub new {
        my($class) = @_;
        return bless {}, $class;
    }
    sub toString { __PACKAGE__ }
}

package ByCodeRef {
    use overload '""' => \&toString;

    sub new {
        my($class) = @_;
        return bless {}, $class;
    }
    sub toString { __PACKAGE__ }
}

package DerivedFromByStr {
    use parent -norequire, 'ByStr';

    sub toString { __PACKAGE__ }
}

package DerivedFromByCodeRef {
    use parent -norequire, 'ByCodeRef';

    sub toString { __PACKAGE__ }
}

say DerivedFromByStr->new();     # "DerivedFromByStr" <- オーバーライドできている
say DerivedFromByCodeRef->new(); # "ByCodeRef" <- オーバーライドできていない

2013-05-21

JSX minifierの圧縮性能

JSX compilerのソースコードで検証してみました。

ModeSize(KiB)Ratio
original15071.00
JSX minifier2770.18
Closure Compiler/D6020.40
Closure Compiler/A3010.20

対象にしたソースコードがJSXから変換したJSというやや特殊な状況ですが、Closure CompilerのADVANCED_OPTIMIZATIONSよりもサイズが小さくなりました。また、ADVANCED_OPTIMIZATIONSと異なりJSX minifier*1はコードを破壊する圧縮は一切行わないので、圧縮したらコードが動かなくなるということが非常に起こりにくくなっています。しかしそれでも、JSXの豊富な型情報を使って圧縮すればADVANCED_OPTIMIZATIONSよりもサイズを小さくできるというわけですね。

実際に使ったコマンドは以下のとおりです。

jsx --version
# JSX v0.9.31
#
# Original
jsx --release src/jsx-node-front.jsx | wc -c
# JSX minifier
jsx --release --minify src/jsx-node-front.jsx | wc -c
# Closure Compiler/D (default)
jsx --release src/jsx-node-front.jsx | closure-compiler | wc -c
# Closure Compiler/A (advanced optimizations)
jsx --release src/jsx-node-front.jsx | closure-compiler --compilation_level ADVANCED_OPTIMIZATIONS | wc -c

*1:JSXコンパイラ組み込みの圧縮+esmangle http://constellation.github.io/esmangle/

2013-05-18

perl v5.18.0 released!

perl v5.18.0 がリリースされました。

このリリースでの新規機能はほとんどないものの、二つの非常に大きな変更があります。

ハッシュキーのランダム化

each(), keys(), values() で返されるハッシュキーの順番がハッシュ毎にランダムになりました。同じプロセス内、同じキーセットのハッシュでさえ順番が一致しなくなります。

use 5.18.0;
use strict;
use warnings;

my %a = map { $_ => 1 } qw(foo bar baz);
my %b = %a;

say join ", ", keys %a;
say join ", ", keys %b;

実行例:

$ perl randomized-keys.pl
baz, bar, foo
foo, bar, baz

これの影響でいくつかのモジュールのテストがfailします。特にJSON::XSがこの変更に引っかかるのが有名で、 id:miyagawa さんが示唆するようにテストせずにインストールするしかありません。

一方で、むやみに--notestでインストールすると本当にモジュールが壊れていることもあるのでその判断は難しくおすすめできません*1。各モジュールが対応するまでしばらく様子をみたほうがよさそうです。

smartmatch / given-when が実験的機能に

スマートマッチ演算子とgiven-when句が実験的とされ、使用すると警告が出るようになりました。スマートマッチは仕様が複雑怪奇でバージョン毎の挙動が微妙に異なるのが問題とされていましたので、一旦リセットして検討しなおすということでしょう。given-whenまでも実験的機能になったのは残念ですが、given-whenはスマートマッチと不可分なので仕方がありません。

no warnings 'experimental'で警告を無効化できます。