Headline About TechLog Download Java VBA Link

February 7, 2008.

寒い話


相変わらず電車が寒い。1時間暖房無し。ちょうど学生がいない時期で、電車が混んでないせいで余計に寒い。先日は眠れないと愚痴を書いたが、うっかり眠ると凍死しそうだ。気管支の強い方ではないので、風邪を引いている人に近づかないようにしているのだが、花粉の季節到来なのか、マスクだらけで見分けがつかない。ロシアンルーレット状態だ。

会社の帰りに「こころにあまいあんぱん屋」という店でパンを買う事がある。ブルーベリー餡、さつま芋餡、マンゴー餡、クリームチーズ餡など個性的なパンが一杯で、しかもどれもとっても美味しい。ただ難点があって、外から見た限りでは区別のつかないものが多いのだ。3つぐらい購入した場合、自分の中で食べたい順番というものがあるわけだが、なかなか見分けがつかない。コシアンルーレット状態だ。

 

いやはや、寒いなぁ。

 

そういえば、本業の方のプロジェクト、一向に前に進みません。トラブってるわけではなく、モノが落ちてこない。ようやく環境設定に入るところ。しかし、16GBのVirtual環境の取得に苦心。HDDが足りない→必死で空ける→サーバに上げたよ連絡→圧縮してある、つまり圧縮ファイル+解凍後の分のHDDがいる→必死で空ける→圧縮ファイル取得→ファイル壊れてて解凍できない→サーバに非圧縮ファイルを置いてもらう←今はここ。

ドキュメント修正から始めてといわれるも、ドキュメントがアプリより古い。つまり、新機能のための修正以前に、ドキュメントをコードに合わせて最新化する作業があり、モジュールによってはコードを読んで0から起こさないといけない。やれやれ。あぁ、別にPLの人が悪いわけではないので誤解の無いように。PLの人も1週間前にこのプロジェクトを引き継いだところなのです。ともかくやれやれ。

しかし、いまどきデスクトップで合計40GB未満のHDDのマシンで開発のはどうよ。XGAだし。この間までメモリも512MBだったし。これはさすがにVirturlPCを使うには足りないので、先日2GBに増設してもらいましたけど。

まぁ、そんな日々です。能率悪い。業界外の人はSEやPGってプログラムをバシバシ作ってるイメージがあるのでしょうけど、コーディングの時間って10%も無い気がするなぁ。こんど正確に測ってみるかなぁ。というかでかい会社のプロジェクトならそれを管理するのが普通。なんにせよ、また一人ぼっちプロジェクトで3月中には実稼動、初の.NET VBって事もあるので、気を抜かずに頑張りましょう。

 

夜はバドミントンへ。頑張りすぎて疲れたので、ソフトの開発はお休み。そういう理由で休むのは良くないのだけど。できればコンスタントにやりたいですね。明日もバドに行く予定ですが、ちゃんと開発もできるように頑張りましょう。

 

 

【JavaのStringオブジェクトは変更不能】

JavaのStringオブジェクトの内容を書き換える事はできない。「は??、何言ってるの、馬鹿じゃないの?」と言われそうだが事実である。反論する人の意見は大抵このようなものだ。例えば以下のようなコードを書いたとする。

String str = "first";

str = "second";

System.out.println(str);

この場合、"second"が出力されるから、strは編集できてる事になるじゃん!と。プログラムの動作はそのとおりだし、仰ることの意味は判る。しかし、とららえるレイヤが違うのだ。

 

Javaはポインタの言語である。もっと正確に言うと参照の言語だ。String型変数はStringオブジェクトの先頭ポインタを指すだけである。Stringオブジェクトを編集したかのような上記のコードは、Stringオブジェクトの先頭ポインタを書き換えただけに過ぎず、オブジェクト自身は精製後、書き換えられる事は無いのである。例えば、以下のようなソースについて考えてみよう。

String str1 = "hello";

String str2 = " world";

str1 += str2;

というJavaの表記は、内部的にはこんな感じで動作している。

String str1 = new String();

char[] buf1 = {'h','e','l','l','o'};

str1.bufPointer = buf1;      //こんな表記は無いよ。あくまでイメージ

String str2 = new String();

car[] buf2 = {' ','w','o','r','l','d'};

str2.bufPointer = buf2;      //こんな表記は無いよ。あくまでイメージ

char[] buf3 = new char[buf1.length + buf2.length];

System.arraycopy(buf1, 0, buf3, 0, buf1.length);

System.arraycopy(buf2, 0, buf3, buf1.length, buf2.length);

str1.bufPointer = buf3;

お分かりだろうか。内部的に連結後の長さの分のデータ配列をnewしなおして、そこに両文字列をコピーし、先頭ポインタを貼りなおしているだけなのだ。Cの人なら、char配列を可変長で扱いたいなら、ポインタ型で宣言して、reallocしてそこにコピーする、という表現が分かりやすいだろうか。Stringオブジェクトとは、ようは文字配列への先頭ポインタと、それを操作するメソッドの集合体に過ぎないのである。

 

上記が、Java docのStringクラスの冒頭に書かれた「String クラスは文字列を表します。Java プログラム内の "abc" などのリテラル文字列はすべて、このクラスのインスタンスとして実行されます。」「文字列は定数です。この値を作成したあとに変更はできません。StringBuffer は可変文字列をサポートします。」という表記の理由である。

上記のような構造のため、Stringの足し算はStringBuffer.append()比べ、異常に遅い。StringBufferは内部バッファを多めにとり、指数関数的に領域を増やしたりという工夫をして、realloc & copyの回数を減らしているから速いのです。

 

この話についてはいずれJavaの格言のどこかに追加しますね。arraycopyも存在を知らない人が多いから、tipsぐらいに乗せてもいいかな。


名前: 意見: パス:

※パスにはこの日記のタイトルをコピペして下さい。

barista:正確には上記のようにバッファの先頭ポインタを差し替えるのではなく、Stringオブジェクトの先頭ポインタを差し替えているらしいです。正規コンテンツ化の際はその辺も踏まえて書きますね。 -2008/02/08 11:05:34


February, 2008
SUN MON TUS WED TUR FRI SAT
12
3456789
10111213141516
17181920212223
242526272829