Java言語プログラミングレッスンとパーフェクトJava
- 2015年03月06日
- CATEGORY- 3. 仕事力{書籍・ツール}
今日はJava言語プログラミングレッスンとパーフェクトJavaについての私の書評です。(←こう書くとなんか偉そうですね)
Java言語プログラミングレッスン 第3版(上)
Java言語プログラミングレッスン 第3版(下)
改訂2版 パーフェクトJava
この本についての印象は、『Javaの基本的な文法とJava(と言うよりオブジェクト指向ってどんなもんか)の考え方についてわりと易しめに書いてある本』です。
そのため、Javaに触れるのが初めての私でも所見ですんなりと概要を理解することができました。
まず、大まかな印象を述べるなら、『手続き型言語(具体的にはVisualBasic6.0を思い浮かべてました)に継承とインターフェースの概念を足しただけ』という感じです。Javaに対して、オブジェクト指向だから取っ付きにくいのかな、という印象を持っていたのですが特につまるところなく理解出来ました。
Java言語プログラミングレッスンは言語特性にも触れられておりますが、それに関して特に詳しく書いてあったのはパーフェクトJavaです。前半部分で出てきた話ですが参考になりかつ面白かったのは、推奨される文字連結の書き方の話です。かなり前半に出てくる話題だった気がしますけれども。。。
文字列の連結時には”+”ではなくStringBuilderクラスを使いましょう、短時間に相当数実行されるプログラムではかなりの実行速度の違いが出るよ、という内容ですのでもはや常識となっている話ですがVB6.0の知識しかない私には大変勉強になりました。
この文字連結の実行速度なのですが、実際に試してみるとすごく違いが出てびっくりしました。
具体的には以下の実験をしてみました。
【実験概要】
アルファベット一文字を10万文字連結
実行回数は100回
最終的な計測結果は平均値を採用
実行開始時間と終了時間の差分を実行時間として計測
実行環境は私のWindowsマシン(スペックはお察しなので公表しません)
実行結果はこんなかんじです。
【”+”の場合】
1 -> 5808 ms
2 -> 6344 ms
3 -> 6819 ms
4 -> 6872 ms
5 -> 6218 ms
6 -> 6394 ms
7 -> 5939 ms
8 -> 5779 ms
9 -> 6062 ms
10 -> 6285 ms
11 -> 5861 ms
12 -> 5846 ms
13 -> 6030 ms
14 -> 5984 ms
15 -> 5847 ms
16 -> 5797 ms
17 -> 5959 ms
18 -> 6757 ms
19 -> 5920 ms
20 -> 6090 ms
21 -> 5975 ms
22 -> 5868 ms
23 -> 5990 ms
24 -> 5982 ms
25 -> 5784 ms
26 -> 5868 ms
27 -> 5970 ms
28 -> 5940 ms
29 -> 5816 ms
30 -> 5846 ms
31 -> 5778 ms
32 -> 5797 ms
33 -> 5771 ms
34 -> 5728 ms
35 -> 5838 ms
36 -> 5803 ms
37 -> 5750 ms
38 -> 5738 ms
39 -> 6181 ms
40 -> 5794 ms
41 -> 5767 ms
42 -> 5780 ms
43 -> 5713 ms
44 -> 6028 ms
45 -> 6186 ms
46 -> 5956 ms
47 -> 5935 ms
48 -> 5960 ms
49 -> 6324 ms
50 -> 5769 ms
51 -> 5821 ms
52 -> 6146 ms
53 -> 6358 ms
54 -> 6270 ms
55 -> 6110 ms
56 -> 5820 ms
57 -> 5935 ms
58 -> 6326 ms
59 -> 6760 ms
60 -> 7176 ms
61 -> 6439 ms
62 -> 6777 ms
63 -> 6306 ms
64 -> 6277 ms
65 -> 6298 ms
66 -> 6069 ms
67 -> 6138 ms
68 -> 6134 ms
69 -> 6227 ms
70 -> 6123 ms
71 -> 6208 ms
72 -> 6162 ms
73 -> 6106 ms
74 -> 6424 ms
75 -> 6421 ms
76 -> 6429 ms
77 -> 6088 ms
78 -> 6040 ms
79 -> 6252 ms
80 -> 5930 ms
81 -> 6266 ms
82 -> 6463 ms
83 -> 6218 ms
84 -> 6207 ms
85 -> 6312 ms
86 -> 6857 ms
87 -> 6418 ms
88 -> 6492 ms
89 -> 6263 ms
90 -> 6635 ms
91 -> 6950 ms
92 -> 7177 ms
93 -> 6209 ms
94 -> 5995 ms
95 -> 6162 ms
96 -> 6073 ms
97 -> 6807 ms
98 -> 6614 ms
99 -> 6608 ms
100 -> 6396 ms
Avg -> 6159 ms
【StringBuilderの場合】
1 -> 12 ms
2 -> 2 ms
3 -> 1 ms
4 -> 2 ms
5 -> 1 ms
6 -> 2 ms
7 -> 2 ms
8 -> 2 ms
9 -> 2 ms
10 -> 4 ms
11 -> 2 ms
12 -> 2 ms
13 -> 2 ms
14 -> 2 ms
15 -> 2 ms
16 -> 2 ms
17 -> 2 ms
18 -> 2 ms
19 -> 3 ms
20 -> 2 ms
21 -> 2 ms
22 -> 2 ms
23 -> 2 ms
24 -> 1 ms
25 -> 1 ms
26 -> 1 ms
27 -> 1 ms
28 -> 4 ms
29 -> 2 ms
30 -> 2 ms
31 -> 2 ms
32 -> 2 ms
33 -> 2 ms
34 -> 1 ms
35 -> 1 ms
36 -> 2 ms
37 -> 2 ms
38 -> 2 ms
39 -> 1 ms
40 -> 1 ms
41 -> 1 ms
42 -> 2 ms
43 -> 2 ms
44 -> 2 ms
45 -> 2 ms
46 -> 2 ms
47 -> 1 ms
48 -> 1 ms
49 -> 2 ms
50 -> 2 ms
51 -> 2 ms
52 -> 2 ms
53 -> 1 ms
54 -> 1 ms
55 -> 2 ms
56 -> 4 ms
57 -> 1 ms
58 -> 1 ms
59 -> 2 ms
60 -> 2 ms
61 -> 2 ms
62 -> 1 ms
63 -> 1 ms
64 -> 2 ms
65 -> 2 ms
66 -> 1 ms
67 -> 2 ms
68 -> 2 ms
69 -> 1 ms
70 -> 1 ms
71 -> 2 ms
72 -> 2 ms
73 -> 2 ms
74 -> 1 ms
75 -> 1 ms
76 -> 2 ms
77 -> 2 ms
78 -> 2 ms
79 -> 2 ms
80 -> 1 ms
81 -> 1 ms
82 -> 1 ms
83 -> 1 ms
84 -> 2 ms
85 -> 4 ms
86 -> 2 ms
87 -> 2 ms
88 -> 2 ms
89 -> 1 ms
90 -> 1 ms
91 -> 2 ms
92 -> 2 ms
93 -> 2 ms
94 -> 2 ms
95 -> 2 ms
96 -> 2 ms
97 -> 1 ms
98 -> 1 ms
99 -> 2 ms
100 -> 2 ms
Avg -> 1 ms
圧倒的じゃないか、我が軍(StringBuilder)は!
まさかの速度差。6159msと1msはちょっと差が激しいですね。
どんだけ”+”を使った文字連結が遅いかっていう話です。
“+”を使うと、
その都度内部的にStringBuilderクラスのインスタンスを生成してから、append呼び出しています。
インスタンス化には非常にコストがかかるため、for文などのループ処理の中で使用してしまうと、
非常に遅くなる可能性を秘めています。
というのも、インスタンス化の処理ってやること多いんですよね。
やることが多いと、なんか大変そうな気がしませんか?
“+”と書いたことにより裏側でどんなコードが実行されているかというと、
StringBuilder strings = new StringBuilder();
ってのが実行されるわけです。
このインスタンス化という処理のステップをざっくりあげてみます。
1.”StringBulider string”の部分でメモリ領域を確保し、
2.”new StringBuilder()”の部分でコンストラクタを呼び出して初期化処理を行い、
3.”string =”の部分で生成したインスタンスの参照値を返却する
と言ったおおまかに3ステップを行っています。
たった3ステップと思うかもしれませんが、これがループの中で繰り返されるとなると
ちりも積もれば山となる、で相当なコストがかかるわけです。
※それぞれの処理について詳しい情報は、パーマネント領域、スタック領域、ヒープ領域、インスタンス化等でググると出てきます♪
で、やっとappendメソッドを呼び出します。
しかも、その後は使わなくなるのでメモリ領域を開放し、
次のループに入った時にまたステップ1からやりなおしになるわけです…。
“+”を使うか、最初からStringBuliderを使うかでものすごい違く処理を効率化できるってことです。
書き方一つでここまで実行速度が変わるとは思いませんでした。
逆に言えば、書き方一つで自分が書いたコードがそのシステムのボトルネックになり得るかもしれません。ちょっと怖いです。
まぁ、といった具合に大切な言語特性に関係する話も書いてあったりして、手続き型から移ってくる人が気が付かなさそうなことも考慮した内容となっており、この3冊はJava初学者にはなかなかおすすめな本のではないかと思います。
パーフェクトJavaは私には難しかったですが、、、他言語習得済の人には、言語特性部分を知るのにとてもいい本じゃないかと思われます。ちなみに、もし私が完全なプログラミング初心者(C言語なにそれレベル)からJavaの学習を始めるとしたら、
Head First Java 第2版 ―頭とからだで覚えるJavaの基本
を、はじめの本に選ぶと思います。(私もこれから読もうと思っています。)どーもこの本、某有名通販サイトのレビューを見ていると肩の力を抜いて読める、しかもわかりやすい本だと書いてあります。なかなか、面白そうです。
積読がたまっているのでまだ手を付けませんが、おそらく夏までには読んでると思います。その前に、わかりやすいJavaEEウェブシステム入門を読んでるかもしれませんけどね。
【関連記事】
日本酒 熱燗の種類
WEB系エンジニアになるために読んだ専門書一覧
- 2015年03月06日
- CATEGORY- 3. 仕事力{書籍・ツール}