喜天華2回目

3ヶ月ぶりに喜天華へ行ってきました。

IMG_20141230_115104

前回通った道を覚えているかどうかの確認と、あらためて頭に刷り込むため、あとは前回初めて行った時に店主が撮ってくださった写真を見るのが目的です。

普段ツーリングには高速道路はほとんど使わず、目的地までの道のりはスマホでGoogle Mapsを時折見ながら、という事がほとんどですが、前回は同僚2人とのツーリングで、先導役をしようと思い前夜にPCでGoogle Mapsとストリートビューを使って予習しておいたのです。
ストリートビューはやっぱりすごいですね。交差点だけでもざっと確認しておけば、実際走る時にその景色を覚えていて、五叉路や浅い曲がり角の交差点等、分かり難い道でも迷いません。

さて、店内で写真を確認します。

IMG_20141230_113117

ありました!天井に飾ってありました。

しかも同僚の分も含めてあと3枚プリントしてくださっていました。ただし同僚の分は「また来てくれた時に渡すね。」と。そうですよね。また連れてきます!

ドラッグスター250 1周年

ドラッグスター250の納車から1年が経ちました。免許取得も納車同日だったので、バイク歴もやっと1年です。明日からタンデムできます。

1年間で消費したガソリンは約200ℓ、走行距離は約7,500km。いろいろなところへ行って、いろいろな人に会いました。

BOLTへの思いが強くなってきてしまっている今日この頃ですが、まだまだ買えませんし、運転技術も未熟ですから、これからもしばらくこの相棒と楽しみます。

低速旋回の猛特訓

人(車)どおりがほとんど無く、周辺に迷惑もかけない広い場所ってどこにあるでしょうか?

バイクの運転技術にはいろいろありますが、低速走行も大きな要素ですよね。ツーリングで目的地に着いてから駐輪場までスムーズに移動させたり、Uターンをスマートに決めたり。
日々運転しているだけではなかなか上手くならないので、低速旋回だけを特訓してみました。

地方へ行けば良い場所があるかも、と特に目的地も決めず走り、宍粟にてひとまず案内標識で見つけたフォレストステーション波賀へ。
山の中にコテージ、キャンプ場の他、地元の名水を使ったコーヒーの喫茶店や公園もあります。今度子どもを連れてきてみよう。

山道途中に広い空き地がないかと淡い期待で登り始めましたが、道が悪くバイクではあまりに怖かったのですぐに引き返しました。

さらに北上して音水湖のさざなみ公園に着きました。まだ早かったためか車は1台も無く、当然人もいません。周辺は低速での走行音なら全く問題無い場所で、もし大きなミスをしても損壊してしまうような物は無く、また一応携帯電話が通じる事も確認できたのでここの駐車場をお借りする事にしました。

IMG_20141130_101633

ほぼ最小回転半径?もっと深い??というような小旋回で、八の字走行を延々と約1時間続けていました。全身に力が入っていた事に加えて、もう11月末ですが天気が良かったため、汗だくでした。

自分なりに見つけたポイントは、

  • 進行方向をしっかり見る事
  • リーンアウトで曲がる事。シートには太ももで乗るぐらい上体を移動させる
  • スロットルを若干開いてアイドル状態より回転数を上げ、速度はクラッチ操作で調整する事

です。
進行方向を見る事は、曲がる際の基本ですよね。なるべく膨らまないようにと意識してしまい、前輪に注目してしまいがちですが、教習の頃、クランク出口からほぼ180度曲がってコースに戻る部分で、教官から「斜め後方を見ながら発進してみたらうまく行くよ」と教えていただき、本当に驚くほどそうなった事を覚えています。
今日あらためて実感しました。

リーンアウトは特に意識した部分です。上体は垂直なのですが、バイクは感覚的には45度ぐらい傾いているのではないか、というぐらい思い切って倒します。この姿勢なら意外と怖さは無く、安定します。
アメリカンタイプのバイクですが、この時ばかりは少々前傾になってステップへの体重配分を増やし、体を右へ左へ動かします。

スロットルについては、アイドル状態でクラッチをつなげたままの速度でも良さそうなのですが、旋回中は、速度が上がりすぎて膨らみ始めたら減速、失速しすぎて内側に倒れそうになったら加速、の繰り返しです。
これをスロットル操作だけで行うと、ギアが1速なので反応がどうしても急になってしまい、細かい動作が困難です。
クラッチで加減速をコントロールするようにし、トルクを少し上げるためにスロットルは若干回しておきます。

ただ、スロットルについては軽二輪ならではの都合で、大型車ならアイドル状態でのクラッチ操作だけでコントロールできそうですね。

人が来られたのを区切りに特訓終了。成果はあったと思います。
帰り道も綺麗な風景が広がっていました。宍粟は大好きです。

IMG_20141130_114946

 

JavaScriptでタコメーター

ドラッグスター250の最高出力は8,000r/minで発生、最大トルクは6,000r/min、と製品仕様にあります。さて、これぐらいの回転数まで上げた時に、いったい何km/hぐらいで走っているのでしょう?

というのも、多くのアメリカンタイプのバイクがそうであるように、ドラッグスター250にもタコメーターが付いていないから、分からないのです。

もちろん、後付けはできるのでしょうけど、減速比やタイヤサイズは分かるのだから、車速から逆算してみよう、という事で、JavaScriptを使ったタコメーターを作ってみました。理論値なので正確ではないでしょうが、参考値としては使えると思います。

tachometer | バイクのエンジン回転数を計算するページ

ギア5速で100km/hまで速度を上げたら、エンジンの回転数は6,209rpmかぁ。最大トルク発生回転数を超えています。なるほど確かに、高速道路では空気抵抗に負けてしまい、がんばっても100km/hぐらいが限界に感じます。

ドラッグスター250の他に、憧れのBOLT、ヤマハの至宝VMAX、その他個人的な知り合いの車種を登録しています。

今のところ機能を実装しただけの寂し過ぎるインターフェースですが、時間を作ってビジュアルも凝ってみたいと考えています。任意の減速比や変速比、タイヤサイズを入力・記録できるようにもして、みなさまから情報をいただけたら良いな、とか。

IIJmio/D SMSでGALAXY NEXUS SC-04Dのセルスタンバイ問題が解決

10月7日から提供が開始されたIIJmio高速モバイル/DサービスのSMS機能により、GALAXY NEXUS SC-04Dのセルスタンバイ問題が解決しました。

これまで、GALAXY NEXUS SC-04DにIIJmio高速モバイル/DのSIMカードを使用していましたが、アンテナピクトが表示されず、deodexedなカスタムROMやその後はroot化不要の方法等でパッチによる対策をしていました。今回SMS機能付きに変えたところ、標準ROMの状態でアンテナピクトが表示されるようになりました。

Screenshot_2013-10-12-22-30-14.png

その結果、セルスタンバイの電池消費量を抑えられています。

Screenshot_2013-10-12-22-11-09.png

ROMは、テザリングを使用したいため、docomo純正ではなくGoogleが提供しているFactory Imageのyakjuを使用しています。これまでは4.2.2を使っており、今回SIMカードの変更と合わせて4.3を焼き直したのですが、APNが自動で設定されました。

Screenshot_2013-10-12-22-30-40.png

キャリアに依るものかROMの設定に含まれていたのかはよく分かりませんが、ROMを焼いただけの初期状態にSIMカードを挿すだけで、SMS送受信とデータ通信が可能です。また、最近のFactory Imageには中華フォントだけでなく日本語フォントが含まれているようで、docomo純正ROMから抜いたフォントをコピーする必要は無く、Google playからGoogle日本語入力等のIMEアプリをインストールすれば、日本語環境も問題ありません。初期の頃から比べると格段に便利になってきています。

壊れたインターホンの応急処置

インターホンが夜中に突然「ピンポーン」「ピンポーン」と繰り返し鳴る…玄関を見ても誰もいない…怖っ

どうやら玄関子機が壊れてしまったようです。
仕方ないので、インターホン親機との結線を外して対処していたのですが、やっぱりインターホンが無いと不便です。
試しに2本の結線を直結してみたら「ピンポーン」と鳴りました。映像や音声の信号も流れるのに意外と単純ですね。鳴らないよりはマシなので、応急処置でスイッチを付けてみました。親機まで壊れてしまうかもしれませんが、買い換えるまでは持ってくれるかな。

IMG_20130521_233921.jpg

赤いスイッチを押すと、インターホン親機が鳴ります。このレトロな感じがなかなかおもしろい。夜中に取り付けて、妻と2人で笑ってました。

使った部品は、電気屋さんで買ってきた一番安いスイッチと、既存配線を傷つけないためのみの虫クリップ、計149円。あと、昔100円均一で買ったものの使っていなかったミニプラグ延長ケーブル。

IMG_20130521_220922.jpg

これらをはんだでつなげてグルーガンで固めただけ…

導通もOKで、玄関子機の結線を外してみの虫クリップに繋ぎ、完了。ひさしぶりの工作でした。

IMG_20130521_225020.jpg

さて、次のインターホンはPanasonicにしようか、インターホンぐらい「アイホン」にしようか。。

ループ展開よりルックアラウンドアサーションの方が速い場合もある

Onemanのテンプレート処理のコードの中で、HTML抽出部分の正規表現にループ展開を用いて高速化する事を課題にしていたのですが、いざやってみると、ループ展開は使わずに元のルックアラウンドアサーションのままが一番速そうだという事が分かりました。
これまでもループ展開の方が絶対に速いと思い込みベンチマークも取っていなかったのですが、分からないものですね。恐るべしオプティマイザ。

やりたかった事

Onemanのテンプレート処理部分をなるべく速いコードに置き換える事。

Onemanはテンプレート処理の最初のフェーズでソースのHTML部分をPerlコードに変換します。具体的には、以下のようなテンプレートの%>と<%で囲まれた太字部分を抽出して、各種エスケープと出力処理に置き換えます。

%><table>
  <caption>環境変数一覧</caption>
  <tbody><%
    for my $key ( sort keys %ENV ) { %>
        <tr>
          <th><%= $key %></th>
          <td><%= $ENV{$key} %></th>
        </tr><%
    } %>
  </tbody>
</table><%

抽出するためのオリジナルの正規表現は以下です。.+?によるマッチの前後にルックアラウンドアサーションで%>と<%を除外するというシンプルなコードでした。

(?<= %> ) (?! <% ) (.+?) (?= <% )

これを、高速化のためにループ展開へ置き換える、というのがやりたかった事です。

試した内容

おそらく最も最適化できていて、タグを優先するか否かが異なる2パターンのループ展開(221、222)とそれに至るまでの計8パターンの正規表現を作成し、オリジナルと比較してみました。

use Benchmark qw( cmpthese );

my $HTML = '%>' . ( << 'END_OF_HTML' x 10 ) . '<%';
    <table>
      <tbody><%
        for my $key ( sort keys %ENV ) { %>
            <tr>
              <th><%= $key %></th>
              <td><%= $ENV{$key} %></td>
            </tr><%
        } %>
      </tbody>
    </table>
END_OF_HTML

cmpthese( 10000, {
    Original => sub { $HTML =~ s{ (?<= %> )
        (?! <% ) (.+?) (?= <% )
    }{$1}gxms; },

    111 => sub { $HTML =~ s{ (?<= %> )
        ( (?: [^<]+ | (?: < (?! % ) ) )+ )
    }{$1}gxms; },

    112 => sub { $HTML =~ s{ (?<= %> )
        ( (?: (?: < (?! % ) | [^<]+ ) )+ )
    }{$1}gxms; },

    121 => sub { $HTML =~ s{ (?<= %> )
        ( (?: [^<]+ | (?: < (?! % ) [^<]* ) )+ )
    }{$1}gxms; },

    122 => sub { $HTML =~ s{ (?<= %> )
        ( (?: (?: < (?! % ) [^<]* | [^<]+ ) )+ )
    }{$1}gxms; },

    211 => sub { $HTML =~ s{ (?<= %> )
        ( (?: [^<]+ | < (?! % ) ) (?: < (?! % ) [^<]* )* )
    }{$1}gxms; },

    212 => sub { $HTML =~ s{ (?<= %> )
        ( (?: < (?! % ) | [^<]+ ) (?: < (?! % ) [^<]* )* )
    }{$1}gxms; },

    221 => sub { $HTML =~ s{ (?<= %> )
        ( (?: [^<]+ | < (?! % ) [^<]* ) (?: < (?! % ) [^<]* )* )
    }{$1}gxms; },

    222 => sub { $HTML =~ s{ (?<= %> )
        ( (?: < (?! % ) [^<]* | [^<]+ ) (?: < (?! % ) [^<]* )* )
    }{$1}gxms; },
} );

221と222はOriginalより圧倒的に速い、と思ったのですが。

結果

Originalが最も高速でした。

           Rate 211 212 112 111 121 122 221 222 Original
211      2323/s  -- -1% -7% -8%-12%-14%-18%-18%     -27%
212      2357/s  1%  -- -5% -6%-10%-13%-17%-17%     -26%
112      2484/s  7%  5%  -- -1% -5% -9%-12%-13%     -22%
111      2514/s  8%  7%  1%  -- -4% -7%-11%-12%     -21%
121      2627/s 13% 11%  6%  4%  -- -3% -7% -8%     -17%
122      2716/s 17% 15%  9%  8%  3%  -- -4% -5%     -14%
221      2824/s 22% 20% 14% 12%  8%  4%  -- -1%     -11%
222      2848/s 23% 21% 15% 13%  8%  5%  1%  --     -10%
Original 3174/s 37% 35% 28% 26% 21% 17% 12% 11%       --

ループ展開のパターンの中では予想通り22○が最も速く、また、○○1と○○2のどちらが良いかはHTMLの書き方に依りそうですが、いずれにしてもOriginalが速いのであれば難しく考える必要はありませんね。

[^<]*および[^<]+にマッチする部分が長い場合はループ展開の方が速いかな、と、タグ文字が無い部分を増やしたHTMLでも試してみましたが、結果は同じどころかOriginalがより速くなりました。もうよく分かりません。。

Oneman 0.27 – テンプレートの一括コンパイル機能

Oneman 0.27を公開しました。

今回の変更はPSGIサーバではなくWAFの方がメインで、テンプレートの一括コンパイル機能を追加しています。

use FindBin qw( $Bin );
require MyWebApp;

my $psgi_app = MyWebApp->psgi_app(
    template_dir => "$Bin/templates",
    precompile => qr/ .html z/xms,
);

template_dirで指定したディレクトリ(指定していない場合はカレントディレクトリ)配下をFile::Findを使ってサブディレクトリも含めて辿り、precompileで指定した正規表現にマッチするパスのファイルを事前にコンパイルします。

通常は、ユーザからのリクエストを受け付けてWebアプリが動いてから、必要になった時に初めてコンパイルされます。マルチプロセスのサーバの場合、このコンパイルはforkされてからの処理になるためメモリ効率が良くありません。

precompileオプションを使い、PSGIアプリケーションをコンパイルする時点でテンプレートもあらかじめコンパイルしておく事で、COWの効果を得る事ができます。

また、PSGIではなくmod_perlの環境では、cache()メソッドを使う事でスマートに書く事ができます。

まずstartup.plに以下のように書きます。

use FindBin qw( $Bin );

require MyWebApp;

MyWebApp->build(
    template_dir => "$Bin/templates",
    precompile => qr/ .html z/xms,
)->cache;

cache()メソッドにより、Onemanのメモリ空間にアプリケーションがキャッシュされます。

次にModPerl::Registryで動作するCGIファイルです。

MyWebApp->cache->run;

これでキャッシュしたアプリケーションが動作します。

この機会に、Onemanアプリケーションの様々な使い方をまとめてみます。

# PSGI ファイル内で完結するアプリケーション
Oneman::psgi_app( sub { ... }, ... );

# CGI ファイル内で完結するアプリケーション
Oneman::run( sub { ... }, ... );

# .pl ファイル内で完結するアプリケーションサーバ
Oneman::psgi_app( sub { ... }, ... )->start(...);
or
Oneman::build( sub { ... }, ... )->start(...); # build は psgi_app のエイリアス

# Oneman を継承したアプリケーションモジュールの $psgi_app
MyWebApp->psgi_app(...);

# Oneman を継承したアプリケーションモジュールの CGI 実行
MyWebApp->run(...);

# Oneman を継承したアプリケーションモジュールをサーバとして実行
MyWebApp->psgi_app(...)->start(...);
or
MyWebApp->build(...)->start(...);

# Oneman を継承したアプリケーションモジュールをキャッシュしてから実行
MyWebApp->build(...)->cache; # キャッシュ
MyWebApp->cache->run(...); # 実行

# Oneman の一部機能(テンプレート処理機能等)だけを使いたい場合
my $oneman = Oneman->core(...);
print $oneman->get_content(...);

ソース

http://www.tamashiro.org/src/Oneman-0.27/
http://www.tamashiro.org/src/Oneman-0.27.tar.gz

Oneman 0.26 – 劇的に速度向上、というかこれまでが遅すぎた

Oneman 0.22で触れたとおり、OnemanはKeep-Aliveの実現のためにselectと1バイト取得の連続でリクエストヘッダの読み込みを行っていたため、ヘッダサイズが大きい場合の速度低下が顕著でした。
でもよくよく考えてみると、Oneman 0.21で実装した入力ストリームのバッファリングをリクエスト処理全体で行えば、リクエストラインとヘッダを取得した際にバッファリングしたリクエストボディやパイプラインリクエストを、後の処理に渡せる事に気付きました。気付くのが遅い。。

そこで、Oneman 0.26では入力ストリームを64KiBずつバッファリングするように変更しました。その結果、速度が劇的に向上しています。

Oneman 0.25 (Keep-Alive)
    Requests per second:    812.36 [#/sec] (mean)

Oneman 0.26 (Keep-Alive)
    Requests per second:    2402.44 [#/sec] (mean)

Starman 0.3008 (Keep-Alive)
    Requests per second:    2412.10 [#/sec] (mean)

Oneman 0.25 (No Keep-Alive)
    Requests per second:    745.69 [#/sec] (mean)

Oneman 0.26 (No Keep-Alive)
    Requests per second:    1325.19 [#/sec] (mean)

Starman 0.3008 (No Keep-Alive)
    Requests per second:    797.39 [#/sec] (mean)

※いずれも、5回×3セット=15回中の最高値を抜粋しています。

このベンチマークはOneman 0.22の時と同様ですが、Keep-Aliveの扱いにミスがあったので、今回は一部を変更しての実施です。

当時Keep-Aliveを有効にするために、Apache Benchにオプション-kを指定していたのですが、あらためて確認すると、Apache Benchの結果がKeep-Alive requests: 0となっていました。なぜKeep-Aliveが無効になっていたか?
確認したところ、まずStarmanは、出力がストリームになっていたためでした。Apache BenchはHTTP/1.0でリクエストを行うため、サーバはchunkedエンコーディングが使用できません。Hello.psgiはContent-Lengthヘッダを持たないため、chunkedエンコーディングが使用できないStarmanはストリームで出力した上でコネクションを切断していました。
次にOnemanは、当時のバージョン0.22ではConnectionヘッダを出力していなかったためでした。Apache Benchは、レスポンスヘッダにConnectionヘッダによるKeep-Aliveの指定が無い場合、コネクションを切断する仕様のようです。バージョン0.25でConnectionヘッダを付加するよう変更したため、現在はApache BenchのKeep-Aliveに対応できています。

ベンチマークに使用するHello.psgiには、StarmanにKeep-Aliveを行わせるためにContent-Lengthヘッダを追加しました。

my $app = sub {
    my $env = shift;
    return [
        200,
        [ 'Content-Type' => 'text/plain', 'Content-Length' => 11 ],
        [ "Hello World" ],
    ];
};

前回と同様に、OnemanとStarmanをそれぞれ以下のように実行して、Apache Benchにより秒間リクエスト処理数を計測します。

$ perl -MOneman -e 'oneman "Hello.psgi", workers => 10'
$ starman --workers 10 Hello.psgi

OnemanもしくはStarmanと、Apache Benchは、いずれもLet’snote CF-R8 (Windows 7) のVirtualBoxで動作するUbuntu上で実行します。Perlは5.16.2、Apache Benchのオプションは以下のとおり。

$ ab -c 10 -t 1 -k http://127.0.0.1:5000/

OnemanとStarmanを交互に3回実行して、それぞれでabを5回ずつ実行、計30回のベンチマークを取りました。
※抜粋のみで詳細の結果は載せていませんが、Onemanの前バージョンとの比較のためバージョン0.25も同様に計測しました。

Oneman 0.26 (Keep-Alive)
    Requests per second:    1730.11 [#/sec] (mean)
    Requests per second:    2344.59 [#/sec] (mean)
    Requests per second:    2368.74 [#/sec] (mean)
    Requests per second:    2316.48 [#/sec] (mean)
    Requests per second:    2391.14 [#/sec] (mean)

    Requests per second:    1700.56 [#/sec] (mean)
    Requests per second:    2317.97 [#/sec] (mean)
    Requests per second:    2358.85 [#/sec] (mean)
    Requests per second:    2402.44 [#/sec] (mean)
    Requests per second:    2366.34 [#/sec] (mean)

    Requests per second:    1803.13 [#/sec] (mean)
    Requests per second:    2362.14 [#/sec] (mean)
    Requests per second:    2322.59 [#/sec] (mean)
    Requests per second:    2381.22 [#/sec] (mean)
    Requests per second:    2377.59 [#/sec] (mean)

Starman 0.3008 (Keep-Alive)
    Requests per second:    1736.05 [#/sec] (mean)
    Requests per second:    2375.56 [#/sec] (mean)
    Requests per second:    2406.15 [#/sec] (mean)
    Requests per second:    2412.10 [#/sec] (mean)
    Requests per second:    2392.75 [#/sec] (mean)

    Requests per second:    1693.59 [#/sec] (mean)
    Requests per second:    2352.28 [#/sec] (mean)
    Requests per second:    2369.86 [#/sec] (mean)
    Requests per second:    2382.01 [#/sec] (mean)
    Requests per second:    2287.22 [#/sec] (mean)

    Requests per second:    1783.65 [#/sec] (mean)
    Requests per second:    2374.16 [#/sec] (mean)
    Requests per second:    2405.08 [#/sec] (mean)
    Requests per second:    2377.22 [#/sec] (mean)
    Requests per second:    2337.31 [#/sec] (mean)

また、Keep-Aliveを使用しない場合のベンチマークも取りました。結果は以下のとおりです。

$ ab -c 10 -t 1 http://127.0.0.1:5000/
Oneman 0.26 (No Keep-Alive)
    Requests per second:    970.57 [#/sec] (mean)
    Requests per second:    1258.08 [#/sec] (mean)
    Requests per second:    1299.39 [#/sec] (mean)
    Requests per second:    1319.84 [#/sec] (mean)
    Requests per second:    1273.80 [#/sec] (mean)

    Requests per second:    930.12 [#/sec] (mean)
    Requests per second:    1307.79 [#/sec] (mean)
    Requests per second:    1313.25 [#/sec] (mean)
    Requests per second:    1325.19 [#/sec] (mean)
    Requests per second:    1279.76 [#/sec] (mean)

    Requests per second:    977.43 [#/sec] (mean)
    Requests per second:    1289.74 [#/sec] (mean)
    Requests per second:    1297.43 [#/sec] (mean)
    Requests per second:    1308.71 [#/sec] (mean)
    Requests per second:    1276.44 [#/sec] (mean)

Starman 0.3008 (No Keep-Alive)
    Requests per second:    616.22 [#/sec] (mean)
    Requests per second:    769.84 [#/sec] (mean)
    Requests per second:    797.39 [#/sec] (mean)
    Requests per second:    756.97 [#/sec] (mean)
    Requests per second:    759.92 [#/sec] (mean)

    Requests per second:    539.82 [#/sec] (mean)
    Requests per second:    736.61 [#/sec] (mean)
    Requests per second:    707.97 [#/sec] (mean)
    Requests per second:    681.39 [#/sec] (mean)
    Requests per second:    728.07 [#/sec] (mean)

    Requests per second:    491.34 [#/sec] (mean)
    Requests per second:    584.63 [#/sec] (mean)
    Requests per second:    668.69 [#/sec] (mean)
    Requests per second:    668.10 [#/sec] (mean)
    Requests per second:    698.69 [#/sec] (mean)

ソース

http://www.tamashiro.org/src/Oneman-0.26/
http://www.tamashiro.org/src/Oneman-0.26.tar.gz