[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[jfriends-ml 12290] [ ズームイン Java]final について( Re: 4/8 のズームイン Java 参加できないので)



高橋(徹)です。

   ""TAKAHASHI, Tomohiro" <t_takahashi@xxxxxxxxxxxxxx>" wrote:

>   なお、ズームインJavaの「Java魂」ですが、先にP45〜P91までを予習
> しまして、素朴な質問・疑問を考えておきました。当日、参考にしてくだ
> さい。(^^;
ありがとうございます。
事前に少し詰めておきたいと思います。

今回のfinal(著者はfinal積極活用派)については、異論も是非聞いて
みたいです。

> ====================================================================
> P49の「この依存関係を自動的に認識する構築環境」とあるが、具体的には
> どのような環境があるか?
Sun Java SE SDKのjavacは依存関係を一応認識してくれます。final定数を
参照するクラスをjavacでコンパイルすると、final定数を定義している
クラスのタイムスタンプを検査してソースが更新されていると判断すれば
final定数定義クラスも再コンパイルします。
しかし、参照が間接的となると、依存関係がないと認識してしまうようです。

antは依存関係を認識せず、個々のソースファイルとクラスファイルの
タイムスタンプだけで再コンパイル要否を判定します。

完全に依存関係を認識する構築環境はあるのでしょうか? 
Jikesとか気になります。

> P52の[例2-6]のコードに
>   public final static void main(final String[] args) {
> というmainメソッドがあるが、final static なメソッドの意味・機能は?

Java言語仕様(3rd Edition)の8.4.3.3で
"A method can be declared final to prevent subclasses from overriding
 or hiding it."
とあります。
「final宣言されたメソッドをサブクラスでオーバーライドあるいは隠蔽する
 ことはできない」

> P71の「Log4J内のisDebugEnabled()メソッドを使うと、if文による比較より
> ずっと時間がかかります」とあるが、
手元のPCで以下3つについての単純計測(超マイクロベンチマーク)しました。
(1) ログ出力メソッド(設定ファイルで出力しないログレベル)
(2)isDebugEnabled()呼び出し(ログ出力しない)
(3)単純if文

結果は以下の通りです。
(1) LOGGER.debug("xxx")          : 11,734 ns
(2) if (LOGGER.isDebugEnabled()) :  2,794 ns
(3) if (doLogging)               :  1,397 ns

プログラム起動後2回目の計測で算出、計測のオーバーヘッド1,117nsです。

>   public static void someMethodBetter() {
>     if( LOGGER.isDebugEnabled() ) {
>       LOGGER.debug("xxxx");
>     }
>     if( LOGGER.isDebugEnabled() ) {
>       LOGGER.debug("yyyy");
>     }
>     ...
>   }
> というコードの事を意味しているのか? 何度もisDebugEnabled()メソッドを
> 呼び出すオーバーヘッドはどの程度のものだろうか?
>   しかし、そもそもdoLoggingというフラグが設けてあるので
>   ...
>   private static boolean doLogging = LOGGER.isDebugEnabled();
>   public static void someMethodBetter() {
>     if( doLogging ) {
>       LOGGER.debug("xxxx");
>     }
>     if( doLogging ) {
>       LOGGER.debug("yyyy");
>     }
>     ...
>   }
> とすることで、時間は掛からないのではないか?
設定ファイルでログレベルを変更し出力を抑制しても、そこを実行するだけで
オーバーヘッドが発生します。1回当たりは大した値でなくても(例えば1μ秒)
繰り返し実行されるコードの中にデバッグログが埋め込まれていると、総和は
無視できない時間となります。

例えば、1秒間に2000回のループを実行している場合、1回のループ中に
デバッグログが20箇所存在すると、上述(1)のログ文の場合で10us*20*2000=
400msのオーバーヘッドとなってしまいます。(2)の場合で1us*20*2000=40ms、
(3)の場合なら0.3us*20*2000=12msとなります。


--
TAKAHASHI,Toru
torutk@xxxxxxxxxxxx