あふひねこのにき RSSフィード

2112-09-03 おしらせ

この日記にあるもの 23:47 この日記にあるものを含むブックマーク この日記にあるもののブックマークコメント

わたしはだれ

サイドバーのプロファイルを見てください。

アイマス関連の活動、動画やSSねこふみにて。

ニコマス関連の活動は、ニコニコ部で。

日常のつぶやきはTwitterに。

データベース

アイドルマスター」タグ付き全動画情報データベースの更新状況と公開場所は「ニコニコ部の日記」です。

データベースについての説明はこちらです。

なお、データベース収集・分析のアイデアがありましたらお声をかけてください。

試験的にデータベースの更新をお知らせするRSSを出力しています。

http://aoineko.ciao.jp/nicodata.rss

GMスクリプト

Fast Look up NicoInfoは、マウス選択箇所やリンク先の動画情報(ニコニコ動画のもの)を表示します。

Pixiv Slideshowは、Pixivの「お気に入りユーザー新着イラスト」ページに“スライドショウ”を追加します。スライドショウでは「次へ」「前へ」のリンクを使って、イラストを見ることができます。

2011-12-31 シンデレラガールズの勢いをちょっと見てみる in pixiv

[][][][][]シンデレラガールズの勢いをちょっと見てみる in pixiv 01:04 シンデレラガールズの勢いをちょっと見てみる in pixivを含むブックマーク シンデレラガールズの勢いをちょっと見てみる in pixivのブックマークコメント

モゲマスのキャラがどれだけ流行ってるのかなーと思ったので、ざっとタグデータを拾ってみました。見ての通り、3つ以上出現したタグを一覧で。

perlのWWW::MechanizeとWWW::Scraperで小一時間ほどでした。スクリプトはこちら

タグ登場数
アイドルマスターシンデレラガールズ180
双葉杏37
三村かな子32
ぽっちゃり24
諸星きらり9
天海春香8
小日向美穂7
龍崎薫6
上条春菜6
島村卯月6
巨乳6
奥山沙織6
前川みく6
神崎蘭子5
萩原雪歩5
川島瑞樹5
C815
ナターリア5
福山舞5
如月千早4
水本ゆかり4
渋谷4
中野有香4
喜多見柚4
柊志乃4
我那覇響4
だいたいあってる4
星井美希3
三船美優3
双海真美3
佐城雪美3
赤城みりあ3
佐々木千枝3
城ヶ崎莉嘉3
ふともも3
ふとましい3
緒方智絵里3
神谷奈緒3
東郷あい3
響をいじめ隊3

OK,時代はニートとぽっちゃりだ!

あと、何気に春香さん強い。そして響はいじめたいほどかわいい!

すでにC81というタグが見える当たり、みなさん行動が早いですね。冬コミ後にもっと変化が出るかも。

トラックバック - http://d.hatena.ne.jp/AOI-CAT/20111231

2011-03-30 CoroでFurl

[][][]測ってみた 23:48 測ってみたを含むブックマーク 測ってみたのブックマークコメント

前回のエントリーブクマコメントに、id:gfxさんからCoroからFurlを使う方法を書いていただいていたので、同じ環境でベンチしてみました。

gfx++

Coro+Furlのコードはhttps://gist.github.com/665488から。

use strict;
use warnings;
use 5.0100;
use Furl;
use AnyEvent::HTTP;
use Coro;
use Coro::Select;
use Coro::AnyEvent;
use Coro::Semaphore;
use Benchmark qw/timethese cmpthese/;


# request
my $url = 'http://ext.nicovideo.jp/api/getthumbinfo/';
my $retry = 3;

open my $fh, '<:utf8', '_tmp';
my @list;
for (0 .. 100) {
	my $line = <$fh>;
	chomp $line;
	push @list, $url . $line;
}
close $fh;

cmpthese timethese 1, {
	CoroFurl => sub {
		my @coros;
		foreach my $url(@list) {
			chomp $url;
		    push @coros, async {
		        print "fetching $url\n";
		        my $furl = Furl->new();
		        my $res = $furl->get($url);
		        print "$url: ", $res->status_line, "\n";
		    };
		}

		$_->join for @coros;
	},
	Coro => sub {
		my $sem = Coro::Semaphore->new(5);
		my @coros;
		for my $video_id (@list) {
			chomp $video_id;
			push @coros, async {
				my $guard = $sem->guard;
				http_get $video_id, Coro::rouse_cb;
				my ($data, $hdr) = Coro::rouse_wait;
				if ($hdr->{Status} =~ /^2/) {
					 #print "finish, $hdr->{Status} $hdr->{Reason} $hdr->{URL}\n";
				} else {
					 warn "error, $hdr->{Status} $hdr->{Reason} $hdr->{URL}\n";
				}
			};
		}
		$_->join for @coros;
	},
};

で、結果。Furlは早いし、Coro::Select使うだけで簡単でいいですね。

Benchmark: timing 1 iterations of Coro, CoroFurl...
      Coro: 22 wallclock secs ( 0.38 usr +  0.11 sys =  0.49 CPU) @  2.06/s (n=1)
            (warning: too few iterations for a reliable count)
  CoroFurl:  8 wallclock secs ( 0.05 usr +  0.05 sys =  0.09 CPU) @ 10.64/s (n=1)
            (warning: too few iterations for a reliable count)
           Rate     Coro CoroFurl
Coro     2.06/s       --     -81%
CoroFurl 10.6/s     416%       --
トラックバック - http://d.hatena.ne.jp/AOI-CAT/20110330

2011-03-28

[][][][][]APIへの問い合わせを高速化したい 01:37 APIへの問い合わせを高速化したいを含むブックマーク APIへの問い合わせを高速化したいのブックマークコメント

結論

Furlは非常に速い。でも、AnyEventの方が仕事が早く終わった。

今回は、相手サーバーが応答してデータを取得するまでの時間の方がボトルネック

なお、結果として次の動画を作るのにとっても役に立った。

D

ときどきAEでAPI叩いているとエラーが返ってきましたけど。

背景

nicomas.sqlite用にデータを取得するperlスクリプトの実行に時間がかかっているのを何とかしたい。

135,000件以上の「アイドルマスター」タグのついた動画があるので、時間がかかるのはしょうがないけど、工夫できないだろうか。

なお、環境はstrawberry perl 5.12.1 built for MSWin32-x86-multi-threadをWindows XPで動かしています。

現状

  1. タグ検索ページをスクレイピングして動画IDを取得
  2. 動画IDリストをもとに、APIへ問い合わせ
  3. 取得データをパースしてDBに格納

一番時間がかかるのはタグ検索ページのスクレイピング。でもこれはニコニコ動画側の負荷を考えてウェイトをいれているし、これ以上早くする気は無い。


二番目がAPI問い合わせなので、ここを改善する。コードはだいたい下のとおり。

# もともとはLWPを使った、いたって普通のコード
my $enc = Encode::find_encoding('utf8');
my $ua = LWP::UserAgent->new;
for my $url (@urls) {
    my $res = $ua->get($url);
    if ($res->is_success) {
        my $content = $enc->decode('utf-8', $res->content);
        # do something
    }
}

Furl編

参考情報とベンチマーク

にひりずむ::しんぷる - 初めての Furlを参考にした。

Kazuho’s Weblog: 5x performance - switching from LWP to Furl & Net::DNS::LiteNet::DNS::Liteを使う方法は、Net::DNS::Liteが上手く動いてくれなかったので試していない。

さくっとベンチマークを取ってみた。実際に使うサブルーチンコピペした。

なお、localhost:5000ではplackupでhttp://ext.nicovideo.jp/api/gettumbinfo/sm9のデータを返すように書いたpsgiを動かしている。

use strict;
use warnings;
use 5.0100;
use Furl::HTTP;
use LWP::UserAgent;
use Benchmark qw/timethese cmpthese/;

# setup vars
my $timeout_in_seconds = 5;
my $count = 1000;

# create HTTP object
my $furl = Furl::HTTP->new(
    timeout   => $timeout_in_seconds,
);

# create LWP object
my $ua = LWP::UserAgent->new();

# request param
my $url = 'http://localhost:5000/';
my $retry = 3;


cmpthese timethese $count, {
	Furl => sub {
		furl_get($furl, $url, $retry);
	},
	LWP => sub {
		lwp_get($ua, $url, $retry);
	},
};

sub furl_get {
	my ($furl, $url, $retry, $wait) = @_;
	$retry ? $retry += 1 : $retry = 1;
	$wait = 0 unless $wait;

	my ($minor_version, $status, $message, $headers, $content);
	while ($retry) {
		($minor_version, $status, $message, $headers, $content) = $furl->request(
		    method => 'GET',
		    url    => $url,
		);
		if ($status == 200) {
			last;
		} else {
			$retry--;
			sleep $wait if $wait;
		}
	}
	return ($status, $content);
}

sub lwp_get {
	my ($lwp, $url, $retry, $wait) = @_;
	$retry ? $retry += 1 : $retry = 1;
	$wait = 0 unless $wait;

	my $res;
	while ($retry) {
		$res = $lwp->get($url,);
		if ($res->is_success) {
			last;
		} else {
			$retry--;
			sleep $wait if $wait;
		}
	}
	return ($res->code, $res->content);
}

結果はこちら。

Benchmark: timing 1000 iterations of Furl, LWP...
      Furl:  3 wallclock secs ( 0.78 usr +  0.48 sys =  1.27 CPU) @ 789.89/s (n=1000)
       LWP:  6 wallclock secs ( 2.42 usr +  0.76 sys =  3.19 CPU) @ 313.77/s (n=1000)
      Rate  LWP Furl
LWP  314/s   -- -60%
Furl 790/s 152%   --

AnyEvent + Coro編

use strict;
use warnings;
use 5.0100;
use Furl::HTTP;
use AnyEvent::HTTP;
use Coro;
use Coro::AnyEvent;
use Coro::Semaphore;
use Benchmark qw/timethese cmpthese/;

# 中略

open my $fh, '<:utf8', 'video_id_list.txt';
my @list;
for (0 .. 100) {
	my $line = <$fh>;
	chomp $line;
	push @list, $url . $line;
}
close $fh;

cmpthese timethese $count, {
	Furl => sub {
		for (@list) { furl_get($furl, $_, $retry) }
	},
	Coro => sub {
		my $sem = Coro::Semaphore->new(5);
		my @coros;
		for my $video_id (@list) {
			chomp $video_id;
			push @coros, async {
				my $guard = $sem->guard;
				http_get $video_id, Coro::rouse_cb;
				my ($data, $hdr) = Coro::rouse_wait;
				if ($hdr->{Status} =~ /^2/) {
					 #print "finish, $hdr->{Status} $hdr->{Reason} $hdr->{URL}\n";
				} else {
					 warn "error, $hdr->{Status} $hdr->{Reason} $hdr->{URL}\n";
				}
			};
		}
		$_->join for @coros;
	},
};

sub furl_get {
	my ($furl, $url, $retry, $wait) = @_;
	$retry ? $retry += 1 : $retry = 1;
	$wait = 0 unless $wait;

	my ($minor_version, $status, $message, $headers, $content);
	while ($retry) {
		($minor_version, $status, $message, $headers, $content) = $furl->request(
		    method => 'GET',
		    url    => $url,
		);
		if ($status == 200) {
			last;
		} else {
			$retry--;
			#sleep $wait if $wait;
		}
	}
	return ($status, $content);
}

AnyEvent::HTTPは同一ホストへのアクセスを4に制限しているので、セマフォで並列を5にする必要はなさそうです。ちょっとCoroを触ってみたかったので、上のようなコードになっています。

結果はこちら。

Benchmark: timing 1 iterations of Coro, Furl...
      Coro: 24 wallclock secs ( 0.25 usr +  0.09 sys =  0.34 CPU) @  2.91/s (n=1)
            (warning: too few iterations for a reliable count)
      Furl:  6 wallclock secs ( 0.08 usr +  0.08 sys =  0.16 CPU) @  6.41/s (n=1)
            (warning: too few iterations for a reliable count)
       Rate Coro Furl
Coro 2.91/s   -- -55%
Furl 6.41/s 121%   --

ご覧の通り、Furlの方が処理は速いけど、AnyEvent::HTTPの方が全ての仕事をやり終えるのが早い。ローカルでデータをパースしたりするともっと差が出るようです。

検証が足りない気もするけど、自分の用途では役に立ったのでここまで。なお、データ収集スクリプトでの実戦投入はまだやってません。

トラックバック - http://d.hatena.ne.jp/AOI-CAT/20110328

2010-11-12 パスワード管理ソフトに悩む

[][]Andoroid, Windows両対応パスワード管理ソフト 23:05 Andoroid, Windows両対応パスワード管理ソフトを含むブックマーク Andoroid, Windows両対応パスワード管理ソフトのブックマークコメント

Galaxy Sを買って、iPod touchWindows XPデスクトップマシンとWindows 7ラップトップ、ついでにUbuntu入れたNetbookを持つ体制となりました。

そんなこんなでパスワード管理がめんどうなのでパスワード管理ソフトを比較検討してみた。

Lastpassはまたこんど。

product1passwordkeepass
licenseproprietaryOSS(GPL)
browserWin: IE 7(32bit), Firefox 3(32bit)
Mac: Safari 4, Firefox 3, Chrome(in progress)
IE(Unofficial), Firefox(Unofficial)
AppleMac, iPhone/iPad/iPod touchMac(Unofficial), iPhone/iPod touch(Unofficial)
WindowsOK(Beta)OK
AndoroidOK(Unofficial)OK(Unofficial, readonly)
Other - Unofficial: Linux, BlackBerry, Palm, ...
トラックバック - http://d.hatena.ne.jp/AOI-CAT/20101112