2010-12-04

PythonのUnicode->UTF-8変換はSJISやEUCへの変換よりもちょっと速い

想像していた通りですが、UnicodeをUTF-8に変換するのは、SJISやEUCに変換するよりもちょっと速いことがわかった。




>>> import timeit
>>> def unicode_henkan(c):
... t = timeit.Timer("a.encode('%s')" % c, "a=u'\u3042'*10000")
... print t.timeit(number=1000)
...
>>> unicode_henkan("utf-8")
0.075012922287
>>> unicode_henkan("sjis")
0.19597196579
>>> unicode_henkan("eucjp")
0.146716833115
>>> unicode_henkan("cp932")
0.21554517746
>>>


ちなみに、timeitは与えられた計測対象のプログラムを内部でpythonのプログラムとして解釈する際に、文字コードのことをあまり考えてくれないようなので、

t = timeit.Timer("a.encode('%s')" % c, "a=u'あ'*10000")

のように書くとUnicodeErrorになります。

2010-09-14

関数呼び出しをタプル形式にして遅延させる関数

関数呼び出しをタプルの情報にして保存するしくみを作った。
これを使えばWEBアプリでリクエストをまたいで関数呼び出しを遅延させることができるようになります。
関数呼び出しをタプル形式にして、memcacheなどに保存しておき、次に来たときに本当に呼び出したり。

# coding: utf-8
import inspect
import imp

def freeze_func(func, *args, **kwargs):
u"""
関数呼び出しを保存可能なタプル形式に変換する。
"""
m = inspect.getmodule(func)
return m.__name__, func.__name__, args, kwargs

def __importer(m, path):
a = imp.find_module(m[0], path)
b = imp.load_module(m[0], *a)
if len(m) > 1:
return __importer(m[1:], b.__path__)
else:
return b

def _importer(modname):
modname = modname.split(".")
return __importer(modname, None)



def unfreeze_func(info):
u"""
タプル形式で保存された関数呼び出しを関数に復元して実行する。
"""
b = _importer(info[0])
f = getattr(b, info[1])
args = info[2]
kwargs = info[3]
return f(*args, **kwargs)

if __name__ == "__main__":
import re
info = freeze_func(re.sub, r"[A-Za-z]", "*", "5-3-1 Asakusabashi")
print info # -> ('re', 'sub', ('[A-Za-z]', '*', '5-3-1 Asakusabashi'), {})
print unfreeze_func(info) # -> "5-3-1 ************"

2008-05-24

Djangoでblogっぽいのを作ったので移動します

Djangoでblogっぽいのを作ったので移動します。RSSも吐いておりますので宜しくお願いします。
→新TekTekBlog

移動の理由:
1. このBloggerでは一切のJavascriptなどが貼れないので不便。アクセス解析の類も一切無理。
2. データのエクスポート機能もないので、書き溜めても外部に効率的に持ち出せない。
3. 自分で作って自分で設置するほうが面白い。

2008-05-23

はてブのホットエントリをなんとなーく分類するPythonスクリプトサンプル

昨日作った、Ward法のPythonバインディングを使って、はてなブックマークのホットエントリをなんとなーく分類するPythonスクリプトのサンプルを書いてみた。

サンプルプログラムは例によって、CodeReposに置きました。

試しに今の時点(5/23 深夜2:06)のホットエントリを分類した結果は以下のような感じです。
なんとなーく、分類されているような雰囲気。
もっと各エントリの情報を取得すれば精度は上がるんでしょうが、今の所はホットエントリのRSS一枚から取得できる情報(今の所タイトル中の名詞と、タグの単語)だけを使って分類しています。

----- 以下、その結果 -----

Group [ 50 ] --------------------
「トレードオフの概念は日本に無いのか」 三菱東京UFJ銀のシステム一本化報道に思う:NBonline(日経ビジネス オンライン)
「トレードオフの概念は日本に無いのか」 三菱東京UFJ銀のシステム一本化報道に思う:NBonline(日経ビジネス オンライン)
なぜか変換できない vs. なぜか変換できる:最近の「MS-IME」は目に余る――よろしい、ならば「ATOK」だ (1/4) - ITmedia +D PC USER
今日から始めるデジカメ撮影術:第97回 一眼レフとボケの関係 (1/3) - ITmedia D LifeStyle
NHK「クローズアップ現代」児ポ法単純所持処罰に絞って特集 - フィギュア萌え族(仮)犯行説問題ブログ版・サブカル叩き報道を追う
<ネットカフェ難民>「しんどい」と訴える妊婦まで 100人の実態調査(毎日新聞) - Yahoo!ニュース

Group [ other ] --------------------
Steve Jobs氏のようにプレゼンテーションをする方法 - builder by ZDNet Japan
調査結果に基づいて合成「人々が最も不愉快になる曲/最も聴きたい曲」:試聴可能 | WIRED VISION
グーグル、検索アルゴリズムを少しずつ明らかに:マーケティング - CNET Japan

Group [ 59 ] --------------------
愛し合うってすばらしい、セックスすると得られる10の効能 - GIGAZINE
はてなクラブ - はてな
十字軍はバカに勝てるか - モジモジ君の日記。みたいな。
「宅配寿司 銀のさら」の自虐CM | DIGITAL DJ
変な人があまりにも酷すぎる件について
高学歴のお嬢様をお持ちの方、教えて下さい - 発狂小町
目を開いているのに閉じていると感じる錯覚作成法 | 医学都市伝説

Group [ 60 ] --------------------
ケーキを売ればいいのに - 福耳コラム
落合博満ガンダム宣言
電撃速報!! Amazonを倉庫代わりにしていた転売厨終了のお知らせ
『らき☆すた』を見た非オタの友人が衝撃の一言 - GilCrowsのペネトレイト・トーク

Group [ 64 ] --------------------
世界のPhotoshopチュートリアル トップ50 - ITクオリティ
光源、光線、光跡を表現するPhotoshopのブラシ -2XGU.NET | コリス
歌舞伎町で遇ったギークなタクシー運転手の編み出した、群衆の英知を活かした馬券購入法 - 雑種路線でいこう

Group [ 68 ] --------------------
人間関係が苦手で社会に適合できない人向けのDVDソフト「ミテルだけ」が登場 - GIGAZINE
YouTubeから削除された動画の墓場「YouTomb」が登場、日本のアニメの削除件数は圧倒的 - GIGAZINE

Group [ 72 ] --------------------
AIR-users.jp - 日本の AIR ユーザのためのハブサイト
js-users.jp - 日本の JavaScript ユーザのためのハブサイト
perl-users.jp - 日本の Perl ユーザのためのハブサイト

Group [ 75 ] --------------------
痛いニュース(ノ∀`):「美少女ゲーム(エロゲ)・アニメは、人間性を破壊し少女殺害事件につながる。販売規制を」…民主党女性議員が請願
「美少女ゲーム・アニメをする人は心を破壊され、人間性を失っているので規制すべき」と主張するトンデモ請願が参議院に - GIGAZINE
痛いニュース(ノ∀`):「ジョジョの奇妙な冒険」、中東で「日本が侮辱」「テレビ局爆破しろ」と批判殺到→集英社、原作の第3部など出荷停止

Group [ 76 ] --------------------
人工知能の叛乱
Gmailの検索オプションまとめ | IDEA*IDEA
マックユーザがインストールしているアプリケーション - soundscape out
[okyuu.com] ソーシャルITメディア
透過をきれいに使ったウェブデザインいろいろ - DesignWalker
特集:Firefox 3とFirebugで始めるJavaScript開発|gihyo.jp … 技術評論社
PHP コード最適化 Best Practices 63+ - カタコト日記

Group [ 77 ] --------------------
「ジョジョの奇妙な冒険」が中東で非難 - 社会ニュース : nikkansports.com
「コーラン読み殺害指示」日本アニメ、中東で非難 - MSN産経ニュース
asahi.com:トヨタ、「カイゼン」に残業代 業務と認定、来月から - ビジネス

Group [ 78 ] --------------------
ヒトラー名言集:アルファルファモザイク
傷つきやすい人はどうすれば強くなる?:アルファルファモザイク
ウマーな牛スジカレーの作り方:アルファルファモザイク
ねとらぼ:米WIREDに「やる夫」の特大AA掲載 ひろゆき氏インタビューも - ITmedia News
1日500アクセス以上のブログは全ブログの●%:Garbagenews.com
@nifty:デイリーポータルZ:50年前の新聞広告

Group [ 79 ] --------------------
MOONGIFT: � ブラウザベースのSubversion管理ツール「USVN」:オープンソースを毎日紹介
CSSで背景画像をリサイズするテクニック:phpspot開発日誌
ナムコの成果主義、有能なゲーム開発者が報われない開発現場

2008-05-22

Ward法のPythonバインディングを作りました。

先日から作っていたクラスタリング(Ward法)のPython用バインディングを作りました。Pythonから一応つないで使えるようになりました。

ソースコードの取得とインストール。


$ svn export http://svn.coderepos.org/share/lang/cplusplus/misc/clustercpp
$ cd clustercpp/python/wardcluster
$ python setup.py build_ext --swig-cpp
$ sudo python setup.py install

サンプル実行。
引き続きディレクトリclustercpp/python/wardcluster内で以下を実行してください。

$ python sample.py
1 + 0 => 4 ( 0.244948974278 )
3 + 2 => 5 ( 0.412310562562 )
5 + 4 => 6 ( 4.80645253132 )
$

ちなみに、今上で動いたsample.pyは以下のようなスクリプトで、4本のベクトルをクラスタリングしています。
from wardcluster import Matrix, DoubleVec, Ward

m = Matrix()
m.append(DoubleVec([1.0, 2.0, 3.0]))
m.append(DoubleVec([1.1, 2.2, 2.9]))
m.append(DoubleVec([0.1, 1.2, 5.0]))
m.append(DoubleVec([0.3, 1.0, 5.3]))

w = Ward()

history = w.cluster(m, 4) #この4ってのは、ベクトルの本数

for h in history:
print h.index1, "+" , h.index2, "=>", h.newindex , "(", h.distance ,")"


メモ--------
* setuptoolsを使ったオシャレなモジュールにするのは断念。(swigの結果ファイルとの調整が難しかった)
* swigのtypemap?とか、そういうのはむずかしくて分からないので、めんどくさいインターフェース。
* あくまで実験的なものですよ。
* 相変わらずswigを理解できていない。
* 今回ベクトルの集合を表すために内部でstd::vector<std::vector<double> >を使うようにしたので、パフォーマンスが落ちています。(将来もとのstd::vector<double>*を使って渡す方式に戻したいものです。。。)

2008-05-20

C++のWard法->g++のオプションで驚異的な高速化

先日から作っているクラスタリングアルゴリズムの一種Ward法のプログラムを今日もいじっていた。

こまごまとしたことをしたのだが、コンパイルオプションをいじると、恐ろしく速くなった。

まず、比較のために、前回の結果。

件数   処理時間(s)    そのうち初期行列作成時間
--------------------------------------------
2352 33.432 6.39

そこに、今回以下のコンパイルオプションをつけてみた。(ちなみにOSX10.4&Intelな白MacBookの環境です。)
g++ -O3 -ffast-math -funroll-loops -Wall -fno-common -march=nocona -o ward -I../include ward.cpp

その結果、以下のように高速化された。
件数   処理時間(s)    そのうち初期行列作成時間
--------------------------------------------
2352 12.628 1.06

シャアではないが、通常の3倍以上の速さである。
C++恐るべし。
分散処理とか考えるのはやはりC++で肝心の部分を書いて、その後なんだろうなと実感しました。

2008-05-16

Python -> C++への移植でどれぐらい速くなったか

先日、Pythonで実装したWard法をC++で再実装し、比較してみた。

まずは、前回のPython版の処理時間を再掲。

件数   処理時間(s)    そのうち初期行列作成時間
--------------------------------------------
196 0.677 0.334
392 2.158 1.356
588 4.636 3.073
1176 18.071 12.088
2352 79.09 49.507


これをC++に移植すると、以下の処理時間に短縮される。

件数 処理時間(s) そのうち初期行列作成時間
--------------------------------------------
196 0.216 0.04
392 0.842 0.17
588 1.627 0.39
1176 7.086 1.57
2352 33.432 6.39

今回は、まずは行列作成部分に、できるだけC++で可能なチューニングを施してある。
樹形図作成部分は、あまり最適化していない。
標準のstd::mapとかstd::vectorを使用しており、特別な数値計算用ライブラリなどは一切使っていない。
また、コンパイル時の様々なコンパイルオプションでの最適化もまだ行っていない。

C++(C)のいい所は、メモリの使い方などをダイレクトに想像しながらチューニングが行える所だろう。
今回も、3重ループの効率化を行うだけで、ここまで処理時間が短くなった。

しかし、作っていて気づいたのは、最適化を意識しないでC++を書くと、Pythonとたいして変わらない処理時間だったことだ。
その証拠に、上の表での処理時間の短縮分のほとんどは、今回意識して最適化を図った行列作成部分のものである。

次は、実際の樹形図作成部分がネックになっているので、この部分をより速くしていきたいと思う。

今回のソースはcodereposに置いておきました。