mieki256's diary



2006/09/12(火) [n年前の日記]

#1 [java][iappli] プリプロセッサを通すことが前提のjavaソースを眺めながら

悩んでたり。eclipse 上に持っていくことはできないかなと。やっぱり、eclipse のコード記述支援機能や、デバッカを使いたい。

しかし、eclipse に持っていくと、#define _DEBUG とか、#ifdef _DEBUG 〜 #endif とか、そのあたりを eclipse から「何コレ?」と言われそう。

ということで、そのあたりを代替する方法をぼんやり考えてみたりして。

もしかすると、間違い || 現状ではまだ上手くいかないことを平気で書いてしまってる || 検証が充分ではなかったりするかもしれんけど。

#ifdef DEBUG 〜 #endif の置き換え。 :

開発用のデバッグ処理を記述する際に、
#ifdef DEBUG
    .....
#endif
という書き方をする場合がある。これは、
static final boolean DEBUG = true;

if ( DEBUG ) {
    ....
}
という書き方ができる。…たぶん。
  • DEBUG には static final を指定してあるので、javaコンパイラは DEBUG を定数として取り扱う。
  • 定数として true が指定してあるのだから、if ( DEBUG ) { ... } は、コンパイラが行う最適化によって、単に ... の部分がコードとして出力される。
  • DEBUG = false とすれば、if (DEBUG ) { ... } は絶対に処理が通らないことになる。と、javaコンパイラは判断してくれるので、最終的にコードとしては出力されない。
よって、目的は果たせる。はず。たぶん。

懸念事項としては、javaコンパイラがそこまで最適化をしてくれるだろうか、という点がある。javaコンパイラはかなりタコなのではないか、信用できん、と言われるかもしれない。

とはいえ、実際に true / false を変更して出力された .jar のバイト数を確認したところ、バイト数が増減していることは確認できた。javaコンパイラもさすがにこの程度の最適化はしてくれてるのではないか、と判断できる。…たぶん。おそらく。

#define 〜 による定数埋め込みの置き換え。 :

定数埋め込みを期待して、
#define SCREEN_W 240
といった記述をすることがあるが。これは、java における定数の記法、
static final int SCREEN_W = 240;
といった形で書ける。

iアプリ開発の初期においては、定数埋め込みをプログラマーが意識的に手作業で行わないと、容量削減に繋がらなかったような雰囲気があったらしく。故に、プリプロセッサで #define を列挙していく方法が当たり前になってる、らしいのだけど。

現状では、難読化ツールと最適化ツールを通すことによって、似たようなことをある程度やってくれる模様。いや、もしかすると javaコンパイラが優秀になって、定数は定数として扱う・埋め込んでくれるようになったのかもしれないけれど。

実際に、
  • static final int 〜 = 〜 の記述のままのソース
  • 手作業で定数埋め込みをしたソース
を、
  1. コンパイル
  2. 難読化
  3. 最適化
  4. .jar 圧縮
を経由させて、最終的に出力されたそれぞれの .jar のバイト数を確認してみたのだけど。単純に定数埋め込みをすれば、その分バイト数が減るといった関係性は特に見出せなかった。それどころか、場合によっては逆にバイト数が増える場面もあったりして首を傾げたり。どうも .jar に圧縮する段階で、バイト数の増え方・減り方が予想しにくくなるような、そんな予感も。

そんなわけで。もしかすると、「プリプロセッサを用いて定数埋め込みをすれば容量が減る」という話は、もはや迷信の類になりかけているのではないか。てなことを思っていたりするのだけど。さて。

#define で処理そのものを定義してる場合は、悩む。 :

例えば、
#ifdef DEBUG
  #define DEBUG_MESSAGE System.out.println
#endif
といった定義をしてる場合。冗長な記述や、関数呼び出しを避けたうえで、同様のことを行う方法はちょっと思いつかない。
if ( DEBUG ) { System.out.println(...); }
といったように長々と書くか。あるいは、
public void DebugMessage(String str) {
    if ( DEBUG ) {
        System.out.println(str);
    }
}

DebugMessage(...);
といったように、関数・メソッドにすることになりそうな。

後者の書き方でも、javaコンパイラ or 最適化ツールが、コードに出力しないよう上手くやってくれるならいいのだけど。そのへん未検証だったり。関数呼び出しまで「これは要らないだろう。関数の中身は空なんだから」と判断してくれるなら助かるのだけど。そこまで判断してくれないなら、空の関数を呼び出すコードが無意味に入り込んでしまって、バイト数が増えてしまう。

前者の書き方をする場合、eclipse 等のコード補完機能を使えば、打ち込む手間隙はそんなにかからないとは思うけど。例えば、syso と打って補完機能を使えば、System.out.println に直してくれたりするわけで。> eclipse。適当な文字列に、適当な補完文字列を割り当てておけば、記述する行為自体は楽になる。はず。

という前提で元になるソースを変換するperlスクリプトを作ってたけど :

作業途中で、画像読み込みに関して、自分のやりたいこととは、ちと違うことに気がついた。全画像を一気に展開するのではなく、必要なときに必要な画像だけ展開したいわけで…。そうなるとあちこち大きく書き換えることになる。うーむ。

…自分が作ったソースを元にして、作業したほうが良さそうな気もしてきた。が、バグが出たときの検証・修正を考えると、できるだけ向こうに合わせておいたほうがいいんだよな。うーん。

以上です。

過去ログ表示

Prev - 2006/09 - Next
1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30

カテゴリで表示

検索機能は Namazu for hns で提供されています。(詳細指定/ヘルプ


注意: 現在使用の日記自動生成システムは Version 2.19.6 です。
公開されている日記自動生成システムは Version 2.19.5 です。

Powered by hns-2.19.6, HyperNikkiSystem Project