Hatena::ブログ(Diary)

tomoemonの日記 このページをアンテナに追加 RSSフィード

2006-10-29 いつも通りぎりぎり

[] UPXによる圧縮

UPXを使うとexeファイルやdllファイルのサイズを実行可能な状態のまま小さくすることができます。Pythonで作ったプログラムもこれを使えばそこそこサイズを小さくして配布することができるんじゃないかなと思います。かなりサイズが小さくなる上、起動速度はほとんど変わらないという代物なのですが、良いことばかりじゃないよという話もあります。


UPX 圧縮するとメモリ使用量が増える事例 - NyaRuRuの日記

UPX 圧縮や .NETJavaJIT メカニズムは,

実行イメージを実行時に展開するという共通点を持っています

実行時に展開するタイプのものはみんな同じようにヒープ上に展開するのでしょうか。


  • UPXのダウンロード

UPX: the Ultimate Packer for eXecutables - Homepage

ページが見つかりません:@nifty

[] pygame2exeを使ってみた

py2exeに挑戦

Pythonで書いたスクリプトはPythonの実行環境があれば、そのまま実行できるがたいていのパソコンにPythonの実行環境は入っていないため、Pythonで書いたプログラムを配布するためには少し細工してやる必要があります。*1


py2exeというツールを使うとPythonで書いたスクリプトをWindows上で動く実行ファイルにすることができます。py2exeを使うためにはまずpy2exeパッケージをインストールする必要がありますので、以下のサイトから落としてきましょう。

FrontPage - py2exe.org


次にsetup.pyという設定ファイルを書く必要があります。setupスクリプトの書き方はPythonドキュメントのdistutilsの中に書いてあります。他の人のをコピペして使ったほうが手っ取り早いのでPygame入門のサイトにあるものを使ってみました。

2 setup スクリプトを書く

no title

C:\Programming\Python\Typing>python pygame2exe.py
Input script directry:./
Setup directry:C:\Programming\Python\Typing
Input starting script:typing.py

とりあえず実行ファイルにしたいスクリプト群の起動スクリプトがあるフォルダにpygame2exe.pyを置いて実行すると良いでしょう。そして、起動スクリプトがあるディレクトリと起動スクリプト名を入力してやるだけです。自分の作ったパッケージもきちんと実行ファイルに含んでくれました。ちなみに以下のようなエラーが出るときがありましたが、何回か同じようにpygame2exe.pyを実行するとうまくいきました。しかし、Errorと出ているのに「この操作を正しく終了しました」とはわかりにくい表現ですね。

RuntimeError: BeginUpdateResource: この操作を正しく終了しました。

完了するとbuildフォルダとdistフォルダが作成されます。distフォルダに必要なものが全て入っているのでこのフォルダごと配布すると良いでしょう。それでは早速distフォルダにある実行ファイルを実行してみましょう。


そして発生するエラー。

実行時に例外が発生するとその旨を知らせてくれるメッセージボックスが出てきて、エラーの詳細がlogファイルに記録されます。ちなみにこんなのが出てきました。もちろん普通にpython typing.pyとして実行したときには発生しなかったエラーです。

Traceback (most recent call last):
  File "typing.py", line 162, in ?
  File "typing.py", line 148, in main
  File "typing.py", line 101, in __init__
  File "typing.py", line 127, in SetScreen
UnicodeDecodeError: 'ascii' codec can't decode byte 0x93 in position 0: ordinal not in range(128)

該当箇所にはこのような記述をしていました。system['caption']にはUnicode文字列が格納してあるので、とりあえずUnicode関連の問題であることは推測できますがそれ以上はわかりません。

pygame.display.set_caption(system['caption'])

検索してみると以下のようにutf-8エンコードしなさいと書いてありました。

since you're getting a UnicodeEncodeError, the "note" object is probably a Unicode string, not a "binary code". to write Unicode strings to a file, you need to decide what encoding to use, and encode the string on the way out. e.g.

nodeFileObj.write(note.encode("utf-8"))

この文章で言いたいことはわかりますが、なぜ実行ファイルにしたときにしかこのエラーは発生しないのかはまだわかりません。とりあえず今は素直にencodeすることにします。

pygame.display.set_caption(system['caption'].encode('sjis'))

これでもう一度やってみるとようやく上手くいきました。やれやれです。


py2exeに含まれるexeとdllをUPX圧縮

別にUPXを試してみるために実行ファイルを作成したわけではありませんがせっかくなので試してみたいと思います。py2exeを使ったときにコピーされるdllや実行ファイルのサイズなどはsetup.pyの書き方で大きく変わりますが、上記のpygame2exe.pyを使ったときには以下のようなdllがコピーされました。それぞれのサイズと圧縮率は以下の通り。

ファイル名圧縮前サイズ圧縮後サイズ圧縮率
msvcr71.dll340KB162KB47.65%
python24.dll1828KB778KB42.56&
SDL.dll284KB117KB41.20%
SDL_image.dll229KB116KB50.44%
SDL_mixer.dll408KB190KB46.57%
SDL_ttf.dll396KB184KB46.52%
w9xpopen.exe5KB4KB77.78%
typing.exe1657KB1613KB97.32%
合計5147KB3164KB61.47%

結構小さくなるもんですね。とは言っても今どき5MBと3MBにどれほどの違いがあるのかというと非常に微妙なところです。実行時のメモリ消費はUPX圧縮する前とした後では後の方が1MBほど増えています。また、普通にPythonコマンドで起動したときと比べると4MBほど増えています。CPU使用率ではどちらもほとんど変化ありませんでした。


実行ファイルにしたときにメモリの使用量が増えるのは、やはりプログラムをまるごとメモリ上に展開しないといけないからなのでしょうか。とりあえず数MB程度の増加であれば問題ないので、これで行くことにしましょう。

[] がらなっがらなっ

1.5リットルガラナ2本目突入。

*1:なぜかIBMのパソコンには最初からPythonが入っていますが・・・