OpenIDでテキストを共有できます
- 新規作成
- OpenIDで認証してエントリーを新規作成します
- 共有
- エントリーにはOpenIDで閲覧と編集に制限かけることができます
- 変更履歴
- 編集履歴もあるので、コラボレーションにも活用できます
新着エントリー
memcached 1.3.3のgrow_stats_bufのpatch
statsでセグフォる件
--- memcached-1.3.3.orig/memcached.c 2009-04-06 18:24:53.000000000 +0900 +++ memcached-1.3.3/memcached.c 2009-04-06 19:00:39.000000000 +0900 @@ -1335,15 +1335,14 @@ } static bool grow_stats_buf(conn *c, size_t needed) { - size_t size = c->stats.size - c->stats.offset; - size_t nsize = size; + size_t nsize = c->stats.size; bool rv = true; - while (nsize < needed) { - nsize = nsize << 1; + while (nsize < needed + c->stats.offset) { + nsize = nsize + 2048; } - if (nsize > size) { + if (nsize > c->stats.size) { char *ptr = realloc(c->stats.buffer, nsize); if (ptr) { c->stats.buffer = ptr;
created by blog.nomadscafe.jp
Classメソッド読み出しの速度
まだ古めかしい世界です
classメソッドの読み出しはobjectのそれと比べて遅い
$ perl class.pl
Rate class_raw class object class_old
class_raw 1449275/s -- -2% -18% -36%
class 1481481/s 2% -- -16% -35%
object 1769912/s 22% 19% -- -22%
class_old 2272727/s 57% 53% 28% --
$ perl -v
This is perl, v5.8.8 built for i386-linux-thread-multi
#!/usr/bin/perl use strict; package Hoge; sub new { bless {}, shift } sub hoge { '1' } package main; use Benchmark; my $object = Hoge->new; my $class = 'Hoge'; Benchmark::cmpthese(2000000, { 'class' => sub { $class->hoge }, 'class_raw' => sub { Hoge->hoge }, 'class_old' => sub { Hoge::hoge() }, 'object' => sub { $object->hoge }, });
created by blog.nomadscafe.jp
TokyoTyrant.pmてすと
Tokyo Tyrantのperlクライアントがでているので、軽くベンチとってみた
Tokyo Tyrantは
$ ttserver
だけで起動。on memoryのhash dbになりますね
このサーバに対して、Cache::Memcached、同Fast、TokyoTyrant.pmで接続してgetの速度を比較してみた
バージョンは
| Tokyo Tyrant | 1.1.11 |
| tokyotyrant-perl | 1.4 |
| Cache::Memcached | 1.21 |
| Cache::Memcached::Fast | 0.08 |
先に結果
$ perl tt_bench.pl
Rate cache::memcached tokyotyrant fast
cache::memcached 7168/s -- -68% -82%
tokyotyrant 22222/s 210% -- -46%
fast 40816/s 469% 84% --
TokyoTyrant.pmはなかなか速い
独自プロトコルで通信できるからですかねぇ
ベンチマークスクリプト
use strict;
use warnings;
use Cache::Memcached::Fast;
use Cache::Memcached;
use TokyoTyrant;
use Benchmark qw/cmpthese/;
my $n = 20000;
my $key = "foo";
my $fast = Cache::Memcached::Fast->new( { servers => ['127.0.0.1:1978'] } );
$fast->set( $key => rand );
my $pp = Cache::Memcached->new( { servers => ['127.0.0.1:1978'] } );
my $tt = TokyoTyrant::RDB->new();
$tt->open("localhost", 1978);
cmpthese(
$n => {
tokyotyrant => sub {
$tt->get($key);
},
fast => sub {
$fast->get($key);
},
'cache::memcached' => sub {
$pp->get($key);
},
}
);
created by blog.nomadscafe.jp
CPAN search - index.html
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="ja" lang="ja"> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> <title>CPAN</title> <link rel="stylesheet" type="text/css" href="reset.css" /> <link rel="stylesheet" type="text/css" href="fonts.css" /> <style type="text/css"> #view { border: none; width: 100%; } #dialog { position: absolute; z-index: 98; top: 0px; left: 0px; border: solid 2px #7ae; width: 20em; } #dialog h1 { padding: 2px 0px 4px 4px; background-color: #7ae; cursor: pointer; font-size: 77%; font-weight: bold; } #message { background-color: #fff; } #search { width: 97%; ime-mode: disabled; } #modules li { display: block; padding: 3px; border-top: solid 1px #ccc; background-color: #fff; cursor: pointer; } #modules.highlight li:hover { background-color: #eef; } #modules li.focused, #modules.highlight li:hover.focused { color: #fff; background-color: #339; } </style> <script type="text/javascript" src="jquery-1.2.6.min.js"></script> <script type="text/javascript" src="jquery.mousewheel.min.js"></script> <script type="text/javascript" src="vars.js"></script> <script type="text/javascript" src="main.js"></script> </head> <body> <div id="dialog"> <h1>CPAN Search</h1> <div class="inner"> <p id="message"><p> <input id="search" name="search" /> <ul id="modules"> <li> </li> </ul> </div> </div> <iframe id="view"></iframe> </body> </html>
created by http://www.hatena.ne.jp/dayflower/
CPAN search - main.js
$(function () { //////////////////////////////////////////////////////////////////////// var use_iframe = false; var wheel_step = 3; var scroll_margin = 1; var max_rows = 25; var page_size = function () { return Math.ceil(rows / 2) }; //////////////////////////////////////////////////////////////////////// var MethodQueue = function () { this.ctor.apply(this, arguments); }; MethodQueue.prototype = { ctor: function () { var args = arguments[0]; this.timeout = args.timeout || 1000; this.latest_only = args.latest_only; this.fns = []; this.timer_id = null; }, clear: function () { this.fns = []; }, append: function (fn) { if (this.timer_id) { clearTimeout(this.timer_id); this.timer_id = null; } if (this.latest_only) this.fns = [ fn ]; else this.fns[this.fns.length] = fn; var self = this; this.timer_id = setTimeout(function () { self._execute(); }, this.timeout); }, _execute: function () { for (var i = 0; i < this.fns.length; i ++) this.fns[i].apply(this); this.clear(); } }; //////////////////////////////////////////////////////////////////////// var modules; var candidates = []; var cursor = 0; var offset = 0; var rows = (max_rows > 0) ? max_rows : 25; var loaded = false; var searched = false; var last_word = ''; var moved = false; var collapsed = false; var row_height = 16; var mods_top = 0; var mq = new MethodQueue({ timeout: 200, latest_only: true }); $('#message').text('loading ...'); function open_url(url, newwin) { if (newwin) { var w = window.open( url, '_blank', 'location=yes,menubar=yes,toolbar=yes,directories=yes,' + 'width=' + window.width + ',height=' + window.height); if (! w) $('#message').text('popup is disabled.'); } else { var v = document.getElementById('view'); if (v && use_iframe) { show_dialog(false); v.src = url; } else { window.location = url; } } } function open_module(newwin) { if (window.bundles_static) { for (var i = 0, n = bundles_static.length; i < n; i ++) if (bundles_static[i] == candidates[cursor]) { open_url( 'http://perldoc.perl.org/' + bundles_static[i] + '.html', newwin); return; } } open_url('http://search.cpan.org/perldoc?' + candidates[cursor], newwin); } function render_candidates() { var n = candidates.length; var items = ''; if (n > 0) { var c = cursor - offset; var r = candidates.length - offset; if (r > rows) r = rows; var is = []; for (var i = 0; i < r; i ++) is[i] = '<li id="module-' + (offset + i) + '">' + candidates[offset + i] + '</li>'; if (c >= 0 && c < r) { is[c] = '<li id="module-' + (offset + c) + '" class="focused">' + candidates[offset + c] + '</li>'; } items = is.join(''); } $('#modules').html(items); } function choose_candidates(w) { var cmp; if (w.match('[^:_0-9A-Za-z]')) { if (w.charAt(0) == '~') w = w.substring(1); try { var re = new RegExp(w, 'i'); cmp = function (m) { return m.match(re) }; } catch (e) { return; } } else { w = w.toLowerCase(); var len = w.length; cmp = function (m) { var s = m.substring(0, len) || ''; return s.toLowerCase() == w }; } searched = false; cursor = offset = 0; candidates = []; if (len == 0) { candidates = modules; } else { for (var i = 0, n = modules.length; i < n; i ++) { var m = modules[i]; if (m == undefined) continue; if (cmp(m)) { candidates[candidates.length] = m; } } } searched = true; render_candidates(); $('#message').text(candidates.length + ' modules selected.'); } function check_search() { var e = $('#search'); var w = e.val(); if (w == last_word) return; last_word = w; mq.append(function () { choose_candidates(w) }); } function make_mouse_moved(m) { if (moved == m) return; moved = m; if (moved) $('#modules').addClass('highlight'); else $('#modules').removeClass('highlight'); } function move_cursor(pos, force) { if (candidates.length <= 0) return; var off = offset; // scroll into view var c = pos - off; if (c < 0 + scroll_margin) { off = pos - 1; if (off < 0) off = 0; } else if (c > rows - 1 - scroll_margin) { off = pos - rows + 1 + scroll_margin; if (off < 0) off = 0; if (off == candidates.length - rows + scroll_margin) off --; } if (! force && pos == cursor && off == offset) return; cursor = pos; offset = off; render_candidates(); $('#message').text((cursor + 1) + ' / ' + candidates.length + ' modules'); } function move_cursor_delta(delta) { var pos = Math.floor(cursor + delta); if (pos < 0) pos = 0; if (pos > candidates.length - 1) pos = candidates.length - 1; move_cursor(pos); } function move_cursor_by_key(key, ctrl, keydown) { if (! searched) return false; var f = true; switch (key) { case 13: /* CR */ f = false; open_module(ctrl); break; case 38: /* UP */ f = false; if (! keydown) { move_cursor_delta(-1); make_mouse_moved(false); } break; case 40: /* DOWN */ f = false; if (! keydown) { move_cursor_delta(1); make_mouse_moved(false); } break; case 33: /* PAGEUP */ f = false; if (! keydown) { move_cursor_delta(- page_size()); make_mouse_moved(false); } break; case 34: /* PAGEDOWN */ f = false; if (! keydown) { move_cursor_delta(page_size()); make_mouse_moved(false); } break; case 36: /* HOME */ if (ctrl) { f = false; if (keydown) { move_cursor(0); make_mouse_moved(false); } } break; case 35: /* END */ if (ctrl) { f = false; if (keydown) { move_cursor(candidates.length - 1); make_mouse_moved(false); } } break; default: break; } return f; } function on_resize() { var wh = $(window).height(); document.getElementById('view').height = wh; if (! collapsed) { var e = document.getElementById('modules'); mods_top = e.offsetTop; var rh; for (var c = e.firstChild; c; c = c.nextSibling) { if (c.nodeType == 1) { rh = c.offsetHeight; break; } } if (! rh) rh = 16; row_height = rh; } var h = wh - 4 - mods_top; rows = Math.floor(h / row_height); if (max_rows > 0 && rows > max_rows) rows = max_rows; // recalculate move_cursor(cursor, true); return true; } function show_dialog(show) { if (collapsed == ! show) return; if (show) { $('#dialog .inner').slideDown( 'fast', function () { collapsed = false; }); } else { $('#dialog .inner').slideUp( 'fast', function () { collapsed = true; }); } } function show_dialog_toggle() { show_dialog(collapsed); } $(window).resize(on_resize); on_resize(); $('#search') .keydown(function (e) { // ignore whitespace if (e.which == 32) return false; if (! loaded) return true; if (e.which <= 48) { return move_cursor_by_key(e.which, e.ctrlKey, true); } else { setTimeout(check_search, 0); return true; } }) .keypress(function (e) { // ignore whitespace if (e.which == 32) return false; if (! loaded) return true; if (e.which == 0 && e.keyCode <= 48) { return move_cursor_by_key(e.keyCode, e.ctrlKey, false); } else { setTimeout(check_search, 0); return true; } }); $('#modules') .click(function (ev) { e = ev.originalTarget || ev.srcElement; if (e.nodeName == "LI") { // 7 is magical, length of "module-" var c = parseInt(e.id.substring(7)); if (c == cursor) { // double click open_module(ev.ctrlKey); return false; } else { cursor = c; render_candidates(); document.getElementById('search').focus(); return false; } } return true; }) .mousemove(function (e) { make_mouse_moved(true); return true; }) .mousewheel(function (e, delta) { move_cursor_delta(-delta * wheel_step); document.getElementById('search').focus(); return false; }); $('#dialog h1').click(show_dialog_toggle); if (window.packages_static) { setTimeout( function () { modules = packages_static.concat(bundles_static); packages_static = []; $('#message').text(modules.length + ' modules loaded.'); loaded = true; choose_candidates(''); }, 0); } else { $.getJSON( "packages.js", function (pkgs) { $.getJSON( "bundles.js", function (bnds) { modules = pkgs.concat(bnds); $('#message').text(modules.length + ' modules loaded.'); loaded = true; choose_candidates(''); }) }); } (function () { var e = document.getElementById('view'); if (e) e.src = ''; e = document.getElementById('search'); e.value = ''; e.focus(); })(); //////////////////////////////////////////////////////////////////////// });
created by http://www.hatena.ne.jp/dayflower/
64bit環境でのmemory-shell.plの結果
ライブラリのメモリ使用状況を手軽にしらべられるツールかいたの
FedoraCore6 x86_64での結果
$ perl memory-shell.pl perl> use DBI 3,698,688 perl> use Storable 4,554,752 perl> use Data::Dumper 2,535,424 perl> use Cache::Memcached 18,837,504 perl> use Cache::Memcached::Fast 6,856,704
tokuhiromの結果と結構違うなー
created by blog.nomadscafe.jp
小数点n桁
intの方がはやい
Benchmark: timing 2000000 iterations of int, sprintf...
int: 1 wallclock secs ( 0.65 usr + 0.00 sys = 0.65 CPU) @ 3076923.08/s (n=2000000)
sprintf: 5 wallclock secs ( 5.42 usr + 0.00 sys = 5.42 CPU) @ 369003.69/s (n=2000000)
use strict; use Time::HiRes qw//; use Benchmark; my $time = Time::HiRes::time(); Benchmark::timethese(2000000, { 'sprintf' => sub { sprintf "%.2f", $time }, 'int' => sub { int($time*100)/100 }, });
created by blog.nomadscafe.jp
DoCoMo::Displayの新機種への対応
Index: t/03_docomo_displaymap.t
===================================================================
--- t/03_docomo_displaymap.t (revision 24544)
+++ t/03_docomo_displaymap.t (working copy)
@@ -1,9 +1,9 @@
use strict;
use warnings;
-use Test::More tests => 2;
+use Test::More tests => 3;
use WWW::MobileCarrierJP::DoCoMo::Display;
my $dat = WWW::MobileCarrierJP::DoCoMo::Display->scrape;
ok scalar(@$dat) > 30;
is scalar(grep { $_->{model} eq 'D905i' } @$dat), 1;
-
+is scalar(grep { $_->{model} eq 'F-01A' } @$dat), 1;
Index: lib/WWW/MobileCarrierJP/DoCoMo/Display.pm
===================================================================
--- lib/WWW/MobileCarrierJP/DoCoMo/Display.pm (revision 24544)
+++ lib/WWW/MobileCarrierJP/DoCoMo/Display.pm (working copy)
@@ -42,7 +42,7 @@
sub _regexp {
return <<'RE';
-<td><span class="txt">([A-Z]+\d+\w*\+?).*?</span></td>
+<td(?: colspan="2")?><span class="txt">([A-Z]+-?\d+\w*\+?).*?</span></td>
<td><span class="txt">.*?(?:</span></td>)?
<td><span class="txt">.*?(?:</span></td>)?
<td><span class="txt">.*?(\d+)×(\d+).*?</span></td>
created by blog.nomadscafe.jp
proxymapper.c
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <signal.h> #include <sys/socket.h> #include <sys/un.h> #ifndef UNIX_PATH_MAX #define UNIX_PATH_MAX 108 #endif const int TIMEOUT = 3; const char SOCKET_PATH[] = "/tmp/proxymapper"; static int sd; static int ast = 0; static void force_close_socket() { if (sd) close(sd); sd = 0; } static void alarm_handler(int signum) { if (ast < 0) force_close_socket(); } static int connect_socket(void) { struct sockaddr_un addr; /* int sd; */ /* here I use global sd */ bzero((char *) &addr, sizeof(addr)); addr.sun_family = AF_UNIX; if (strlen(SOCKET_PATH) >= UNIX_PATH_MAX-1) { exit(1); } strncpy(addr.sun_path, SOCKET_PATH, UNIX_PATH_MAX-1); sd = socket(PF_UNIX, SOCK_STREAM, 0); if (sd < 0) { perror("socket"); exit(1); } if (connect(sd, (struct sockaddr *) &addr, sizeof(addr.sun_family) + strlen(addr.sun_path)) < 0) { /* perror("connect"); */ return 0; } return sd; } static FILE * connect_to_remote(void) { int sd; FILE *sp; sd = connect_socket(); if (sd <= 0) return NULL; sp = fdopen(sd, "r+"); if (sp == NULL) { /* perror("fdopen"); */ force_close_socket(); return NULL; } if (setvbuf(sp, NULL, _IONBF, 0) != 0) { /* perror("setvbuf"); */ fclose(sp); force_close_socket(); return NULL; } return sp; } static char buffer[1024]; static const char * comm_with_remote(FILE *sp, const char *message) { ast = -1; alarm(TIMEOUT); ast = (fputs(message, sp) < 0); alarm(0); if (ast) return NULL; ast = -1; alarm(TIMEOUT); ast = (fgets(buffer, sizeof(buffer), sp) == NULL); alarm(0); if (ast) return NULL; if (strlen(buffer) == 0 || buffer[strlen(buffer) - 1] != '\n') { force_close_socket(); return NULL; } return buffer; } int main(int argc, char *argv[]) { FILE *sp = NULL; signal(SIGPIPE, SIG_IGN); signal(SIGALRM, alarm_handler); /* set stdout to unbuffered mode */ if (setvbuf(stdout, NULL, _IONBF, 0) != 0) { perror("setvbuf"); exit(1); } while (fgets(buffer, sizeof(buffer), stdin)) { if (strlen(buffer) == 0) continue; if (buffer[strlen(buffer) - 1] != '\n') { /* continuous => slurp, and error */ while (fgets(buffer, sizeof(buffer), stdin)) { if (strlen(buffer) == 0) continue; if (buffer[strlen(buffer) - 1] == '\n') break; } fputs("NULL\n", stdout); continue; } if (! sp) { sp = connect_to_remote(); if (! sp) { fputs("NULL\n", stdout); continue; } if (comm_with_remote(sp, buffer) == NULL) { /* unrecoverable error */ fputs("NULL\n", stdout); continue; } } else { if (comm_with_remote(sp, buffer) == NULL) { /* reopen */ sp = connect_to_remote(); if (! sp) { fputs("NULL\n", stdout); continue; } /* 2nd try */ if (comm_with_remote(sp, buffer) == NULL) { /* unrecoverable error */ fputs("NULL\n", stdout); continue; } } } fputs(buffer, stdout); } if (sp) { fclose(sp); force_close_socket(); } return 0; }
created by http://www.hatena.ne.jp/dayflower/