日々のつぶやき(98/7/1〜)

1998/07/15(Wed)

昨日の最適化処理の続き。profileをとってみたら、やっぱりまだ最短距離を調べるルーチンが時間がかかっている。と言う訳で、昨日作ったテーブルサーチルーチンに手を入れて、オプティマイズを試みる。試してみたのは、テーブルの行ごとにその行の中での最小値のインデックスを行ごとに憶えておく事だった。

簡単に書くと難しいが(^_^;、そんなに難しい事ではない。{ 10, 12, 5, 15, 14}という行があったとする。そしたら、最小値は5だから、そのインデックス 2(0, 1, 2...と数える事に注意)をどこか別の所に憶えておけば、その行のデータに変更が加わらない限り、最小値が何かというのを(行に限れば)再計算しなくてすむというアルゴリズムだ。そのかわり、メモリは食うが(^_^;、この場合には1つの点につき、sizeof(int) 分だから大した増加ではない。まあ、誰にでも思いつくような最適化であるが、距離の比較の回数が O(n^4) から O(n^2) にまで減るはずなので結構早くなるんじゃないかと期待した。

ところが、1000個の点に関するデーターでprofileを取って見ると、確かに距離を比較している所ではかなり処理時間が圧縮できたが、行の変化に対して、最小値が何かを同期させなくてはいけないので、そこの部分で時間がかかってあまり全体の処理速度は上がらなかった。といっても、全体で30%位処理速度が上がっているので、やらなかったよりマシなのだが…。

不満足とはいえ、一応、そこそこの処理速度(といっても大規模なデータを食わせれば遅くなるのは目に見えているが)を得られたので、上司のNさんに報告。「もうちょっと速度的には何とかなると思います。」と言ったら、「速度が上がるのはうれしいけど、ちゃんと動いているんだろうな」とクギを刺される。動作が正確であることはかなり自信があったので、「大丈夫です」と答えておく。まあ、念のため、今まで最適化したコードが全部同じ出力をするか調べる事にした。どうせ、他にやることないし。(^_^;

で、最適化コードが正しいか調べているうちに顔が真っ青になる。最適化をする前と最適化をした後で、全然出力結果が全然違う。(!_!)何度読み直しても、ロジックとしては同じことをやっている。で、最適化は、点同士の距離を求める所しかやっていないのだが、そのロジックは、「一番遅い奴」「テーブルを使った奴」「テーブルの最小値を代表値として使った奴」の3種類あって、3種類とも全部違う結果を出してきた。やっていることは同じのはずなのに、なんでこんなに違う結果が出るんだ?訳が分からん…。

一体どうして何だろう…って、実は会社から帰る直前に原因に気がついたんだけど、それは明日のネタにとっておこう。(^_^;

1998/07/14(Tue)

昨日作ったコードをdebug。といっても、昨日コーディングした部分はそんなに大した処理をやっているわけではないので、30分ほどdebugしただけで小さめのデータ入力に関してはあっさりと動き始める。もっとも小さめのデータで3分くらいかかっているから大きめのデータではとんでもなく遅くなる事が目に見えているのだが、滑り出しとしては順調。

で、少し大きめのデーターを放り込んで動かしてみたら、ばったりと動かなくなる。おかしいなぁと思って、色々調べてみるのだがdebuggerで見ている限りではちゃんと動いているようにみえる。じゃあ、動いてはいるんだろうな、ということで試しに最後まで動かしてみたら、処理を終えるまでに30分近くもかかってしまった。(+_+;)遅くなることは分かっていたが、いくらなんでもこれじゃあ遅すぎる。と言う訳で、早速処理速度向上に取り掛かる。

で、一番時間のかかっている所は、認識辞書のIndex作成部分だというのははっきりしていた。で、index作成部分で扱っている問題を簡単に解説すると、まず n 次元(という言葉に拒否反応を示す人は平面で考えて下さい。)にいくつか(やっているのは500〜1万程度の点の数)が散らばっているとする。で、その点を距離が近いもの同士でいくつかの(やっているのはグループ数が200〜300)グループに分けるというものだ。で、ちょっとややこしいのは、「こいつとこいつが同じグループ」と決まったら、次回以降の距離の計算をグループに属する点の平均座標から算出する事だ。(このルールが無ければ、点の距離で点の組み合わせをソートしてグラフをつなげておしまいなのだが。)

とりあえず最初のバージョンでは距離の最小値を求めるのに、馬鹿正直に距離を計算していた。(だって、何にも考えなくても組めるんだもの。(^_^;)で、小さめのデーターでprofileをとって、どこでどれくらい時間を取っているか調べると、案の定距離を計算するルーチンがやたらと呼ばれて、時間のほとんど80%以上を消費している。これはいかん、ということで、一回計算した距離は必要がない限り再計算しないようにした。もっといい方法があるのかも知れないが、とりあえず、一回計算した結果をテーブルに記憶する事で、高速化を図る。これは少し追加コーディングとdebugに時間がかかったが、さすがに効果テキメンで、小さめのデータ(500個の点を200グループに分割)なら、30秒くらいで処理できるようになった。でも、このテーブルって、3000個の点を処理するだけで、9Mbyte以上もメモリを消費するという(実際はテーブルの線要素にCWordArrayを使っているので、もっと消費しているはずだが。(^_^;)メモリ馬鹿食いテーブル。仮想記憶と搭載メモリ量に感謝。(^_^;

profileを取って見ると、やっぱり距離の最小値を計算する所で相当時間を食っている。もうちょっと何とかできるだろうな、とは思ったが、とりあえず今日はここまで。

1998/07/13(Mon)

金曜日に指示された認識辞書のIndex部分のコーディングを行う。将来データ構造のアクセス方法や、格納方法を変える事で、もっと処理速度を上げなくちゃいけないのだが、とりあえず動くものを作って、どこに時間がかかっているか見極めるというのを方針にする。まあ、処理速度をあげるにしても、動作仕様を拡張するにしてもある程度目星をつけてあるから、そんなに大変なことにはならないだろうと思っている。もっとも処理速度に関しては、もともと計算量が多いのだからどうがんばってもそんなに早くならないとは思っている。とりあえず、コーディングは一応終って、コンパイルも通るようになったので、明日はdebug。比較的ちゃんと仕事をした日かな?(^_^;

うまくいけばいいんだが。まあ、水曜日くらいには、最悪今週中には何とか目処がつくだろう。最初、上司のNさんが「火曜日までにお願い」とか冗談で言っていたのだが、実はあと1時間残業すれば今日中に出来たかもしれない。(^_^;いや、そうすると明日の仕事がなくなってしまうって、窓際社員なんてのはこんなもの。そろそろ私はリストラ対象かな。(^_^;)

もっともこんなに早くコーディングできるのは社内だけで使うツールだと割り切って作っているから、エラー処理とか処理速度なんてのは二の次でやっているせい。高速化とかのテクニックは全然使っていないし、メモリはがんがん使いまくっている。これじゃあ、本来全然パッケージ製品としては実用的じゃないかもしれない。

ただ、今ぱっと計算してみたら、辞書のサイズが(私の関係しているアプリケーションだと)1M〜2Mで、それをオンメモりでレコード分割しながら読み込んでいても、せいぜい3Mbyte。いろいろ無駄な処理とかデータの取り方をしている所とか(もちろん、読みやすくするため…といいたいのだが、この場合はあんまり考えていないせい(^_^;)、C++を使うメモリ使用上のデメリットはあるけど、それにしたって瞬間的に+1Mbyte位の余計なメモリ消費量で済みそう。そう考えると、そんな瞬間的な+1Mbyte程度の消費量を最適化しても高が効果は知れている。まあ、普通のアプリケーションだったら、メモリ消費量が10M位瞬間的に増えても問題ないと思うんだけど。ただし、これは、普通のアプリケーションなら。そういえば、うちの会社は普通のアプリケーションじゃない奴が目白押しだった。(^_^;

昨日の失態について、議事進行役のMさんにお詫びの電話を入れる。Mさんは気にしていないという事だったので、一安心。ただ、あっさり「あぁ、あれはあれでいいんです。」みたいなことを言われると、こっちは怒鳴られモードしか想定していなかったので、もうしどろもどろ。(^_^;Mさんが温和な人で助かった。

この件について考えてみるに、なんか最近自分自身の心が狭くなったというか、自分以外の人に対する許容範囲ってのがどんどん狭まっているような感じがする。いかんなぁ。

1998/07/12(Sun)

午後1:00にヤネコン実行委員長からお呼びがかかるので、出席。で、1日終り。最後のほう6時以降になったら、なんだかいい加減議事が進まないのに、じれてきてしまう。じれて来てしまった結果、議事進行役の人に「いい加減、さっさと議事を進めて下さい。」みたいな感じの事を言ってしまう。「ああ、あんなことを言わなければ良かった」と後悔しても、後の祭の自己嫌悪。ミーティングから戻ってからずっと悩む。明日にはなるべく早く謝らないといけないな。

1998/07/11(Sat)

お昼を過ぎてからのろのろと起き出したら、母親がおじさんの家に車でつれて行って欲しいという。まあ、急いでやらなくちゃいけない事もないだろうからと安請け合い。で、おじさんの家についたら、やれお茶を飲んで行けとかで引き止められる。まあお茶を飲むくらいならと言う訳で、しばらくおじさんのうちでお茶を飲みながら、世間話。といっても、畑のこととか話されても私はちんぷんかんぷんなので、にこにこしながら聞いているだけ。

おじさんの家を後にしたあと、おばさんを乗せて、近くの本屋に行く。まあどうせ今日行かなくても、明日本屋には寄る積もりだったし、まあいいか。でも実際に行ってみると何か母親とおばさんが気になってゆっくり本を選べない。(^_^;こいつが友達同士だと平気で20分くらいは待たせちゃうんだけど。(^_^;

父親の車のクーラーが壊れているので、修理工場に持って行った。なんか、ヒューズとかを調べていたらしいが、車を預けることになった。で、その修理工場から1時間ほど歩いて帰宅。結局これで1日終ってしまった。

1998/07/10(Fri)

明日は休みだ、ほほいのほい。

のろのろと仕事をしているうちにあっという間に一週間経ってしまう。まあ、何にもやっていなかった訳じゃなくて、今週は、先週作った辞書出力プログラムの動作確認用のプログラムを作ったりしていたのだが、プログラムのスタイルとか変な事にこだわって、あちこち資料を漁ったりしていた。まあ、のんびりと仕事をするってのはいい。

幸い2日ほどかけた動作確認用のプログラムも大した不具合もなく、ほとんど一発で動いてくれたし、動作確認用のプログラムにかけてみたら、1ヶ所だけマイナーなバグと、渡された仕様書の記述ミスを2ヶ所見つけた。まあ、のんびり仕事をしているからこんなものかな。マイナーなバグは、ある条件下でのデータをソートし忘れただけ(実質上は問題がない)だったのだが、qsortを呼び出す時に、比較関数の引数をキャストし間違えてそれに気がつくまで10分ほどかかる。バカ丸出し。(^_^;

辞書出力プログラムと、動作チェック用のプログラムとが同じ間違いをしでかさないように、動作チェック用のプログラムは全く1から書き直した。辞書出力プログラムのほうはMFCだのテンプレートだのを使いまくっているが、動作チェック用の奴は、MFCもクラスも使っていないという感じで、全然別物。まあ、書いている奴が同じだから辞書構造で勘違いしていれば終わりなんだけど。(^_^;クラスとかテンプレートとかを使わないんだったら、Cで書いてもいいと言われるかも知れないが、今更malloc/freeを使って云々なんてかったるくてやってられないのでnew/deleteをガシガシ使いたいから、やっぱりC++。(^_^;その程度だったら、Cで書き直せって言われればすぐに書きなおせるんだけど、やっぱ面倒じゃん。(^_^;

サポートからMicrosoft Word(以下MS-Word)との関連で質問を受ける。私の受け持っている部分にある文書構造をRTFにして出力するって部分があるのだが、これが縦書き文書をRTFに出力した時に、なぜだかレイアウト枠が縦に間延びしてしまうということだった。

いろいろ試してみると、こっちはそこそこRTFの仕様書通りに書いているはずなのに、MS-Wordがうまく解釈してくれないということが分かった。言語道断な事に、MS-WOWRDが起動していない状態で「start foo.rtf」とやったときにはちゃんと指定した通りのレイアウト枠が出てくるRTFファイルでも、同じファイルを、MS-Wordを立ち上げてから[開く]-[foo.rtf]とやったときには、変なレイアウト枠が出来てしまう。こんなのMS-Wordのbugじゃん。(-_-;)

ちなみに会社にあったWindows用ワープロを片っ端からインストールして確かめてみたが、こんな変な動作をするのはMS-Wordだけ。もっともこれは他のどのワープロもRTFの縦書きとかレイアウト枠に対するサポートを放棄しているから問題が起きないってだけの話なんだが。(^_^;せっかくこっちがレイアウト枠の情報とか渡しているんだから、RTFリーダーのワープロの方でもまともに解釈してくれよっていいたくなった。RTFリーダーが手を抜いた所を尻ぬぐいをさせられるのは、関係のないRTFライターのプログラマーだってのは勘弁して欲しいぞ。(-_-;)

RTFの障害を持ってきたサポートのSさんが「『MS-Wordだったら縦書き表示の再現も出来ますよ』っていうんですけど、なんかMicrosoftの宣伝をしているみたいでねぇ…。」と言っていたのが印象的。これは確かに私もなんだかなぁと思うけど、現実的に他のアプリケーションからレイアウト情報付きの文書が流れてくるってのをちゃんと意識して作っているのは、MS-Word以外にないような気がするから、仕方がない。まあ、OLEサーバーを作っちゃえば自分で好き勝手にできるんだけど、じゃあそうするとRTFって何?ということになってしまうし。(^_^;第一、OLEサーバーなんて作るの面倒そうだしぃ。(結局それかい)

まあちょっとでも怒り狂うユーザーの目先が移れば…という訳で、現行のプログラムにちょっとしたパッチを当てる。で、このパッチなんだが、修正内容は論点のすり替えでしかないので、ちょっと後ろめたい。ただ、まともに修正するとなると、RTF出力部分を全部書き直さざるをえないほどの変更になるので、さすがにそこまでは出来ない。あの1万行以上あるプログラムを1week程度で全面rewrite…。考えただけでも恐ろしい。(^_^;

で、とりあえず修正プログラムが出来たので、それを社内メールにしてSさんに送ろうと思って気がついた。Sさんと同じ名字の人が社内に3人いて、一人は古株だから間違いなく別人だと分かる。残りの二人も見当は付くんだけど、どっちがメールを送りたいSさんなのか分からない。今まであまり仕事ではSさんと接点がなかったので、メールを送るために必要なフルネームまで知らなかったのだ。(^_^;今更「すいません、フルネームを教えて下さい」とか聞いたら「今更何を言っているんだぁ〜」とか怒鳴られるだろうなぁとか考えたが、まあ怒鳴られても「聞くは一時の恥」ともいうし、と覚悟を決めて名前を聞きに行った。

幸い(?)、Sさんがいなかったので、たまたま残業していたMさんにSさんのフルネームを教えてもらう。「今更Sさんにフルネームを聞いたら、私怒られるだろうね。」などと軽口を叩いたら、Mさんもけらけら笑っていた。ふっふっふ、否定しなかったな。(☆_-)キラーンこの件でSさんにどやされる状況になったら、一人で地獄に落ちるのは嫌だから、「ああ、あの時にMさんも同意したんですよ〜」とかこじつけて一緒に地獄に落ちてもらいましょう。:-)

ちなみに、このSさん。美人で、頭いいです。一緒にお酒を飲んでいても楽しい人です。で、この取ってつけたようなセリフを言い訳でも、最後につけ加えないと後が恐ろしいという、そんな人です。(^_^;;(って言わなきゃいけないほど…モグモグ)

1998/07/09(Thu)

母親の状態は比較的回復したらしく、若干動きが鈍い気がするがそこそこ歩き回っているので、安心して会社に行く。

会社では、昨日突然休んだ事に対していろいろ憶測が流れていたらしい。有力な説とされたのが、「前夜サッカーを見ていて遅くなったんだろう」というもの。ふ、ふ、ふ、その試合はチャンとビデオにとってあったのさ。B-)まあ、これも日ごろの行いがなせる噂というべきか。(^_^;

7/3の日記についてrumbaさんからの感想。

そもそも初心者だったらポインタへの整数の加算は思いつかないと思う…。

確かに、ポインタ演算がちゃんと出来るようになるとC初心者卒業というのはよく言われるから、 初心者というのは言い過ぎだったかも。とはいえ、Cを使い始めてから10年以上、実務でC/C++を使い始めて4年にもなるんだから、それを考えたら信じられないくらい大馬鹿なミスだったといえる。べつに特にデータ構造が複雑なわけじゃないんだしね。


ファイルのヘッダを読むのに WORD のポインタを使ってはいけませんな。

ポータビリティを考えたら BYTE 単位で読んでから WORD に直すべきです。

お説ごもっとも。ぐうの音の反論もございません。(_ _;;初心者向けに解説すると(といってもこのページの読者には釈迦に説法だが…)普通はBYTE単位で読んで、WORDに再構成する部分は関数にするか、速度的に問題があればマクロにすると思う。(普通はマクロにすると思う。)例えば、こんな関数(もしくはそれをマクロ化したもの)を使うんじゃないかな?


WORD Read86Word(LPVOID lpBaseAddr, DWORD dwOffset)

{

	LPBYTE lpByteAddr = (LPBYTE)lpBaseAddr;

	return lpByteAddr[dwOffset] + lpByteAddr[dwOffset + 1] * 256;

}

符号付き変数を返す時にはもっと小細工が必要なので注意。

ビル・トッテンのページ。反論がないわけではないし、正論過ぎて受け入れられない面もあるのだが、おおざっぱにいってそんなに無茶な事を言っているとは思えない。どちらかといえば、まともすぎて、かえって怪しいくらいだ。(^_^;ともあれ、ある程度投票率が多くないとまともに民主主義が機能しないというのはその通りだと思う。(どこかの田舎みたいに投票率98%以上なんてのも異常だとは思うが。)

「気に入った政党がなければ最悪の政党以外に投票して最悪の政党を落とすための努力をする」ってのは、盲点だった。死に票覚悟の投票行動だけど、この党に勝たせるくらいだったら、別政党に勝たせようとするってものありだと思う。少なくとも白紙委任状を与えるよりはよっぽどマシ。しかし、投票しなかった人への増税ってことを訴える候補っていないかな。年金だってこの前大赤字を出したことだし、いずれは大増税をせざるをえないのは目に見えているはずなのだが。

そういえば、あの年金の大赤字を出した責任って誰がどのように取るんだろう?あの1兆円以上の大赤字。どうせ私の世代なんかはまともに年金なんかまともな生活を送れる程度のレベルでは受けとれないと分かっていつつ納めている訳だが、それさえも収支とんとんで行った場合の話。これじゃあ、近々年金保険料の大幅増額は間違いないだろう。なんのことはない、これじゃ準官僚の尻ぬぐいを保険料の増額でやっているってだけじゃないか。

山一證券がつぶれた時には社長が涙ながらに記者会見で詫びを入れて、もちろん詫びを入れたから済む訳じゃなくて、その後色々刑事?民事責任が追求されているのだけど、今度の話では誰が悪いとか、誰が責任者だったとか全然聞かない。目先の聞かないディラーだったらすぐにクビになって当然だし、1兆円も赤字を出したんだったら当然その責任は追求されるべきだと思うんだけど、なんにもないみたい。一体どうしてなの?

で、某政権政党は今頃になって減税が云々といっているし。お前、ここまで減税って言っていなかったんだから、今頃言ってもなんだか、昨日の世論調査を受けてという感じで、政策というよりは票稼ぎという感じでいやらしい。そういえば、その政党の候補がお昼休みに「逆風が吹いていますが、是非応援して下さい」とか言っていた。逆風って…。一体誰が政権を握っていてこんなに不景気になったというのだ?それを考えればここで逆風が吹くのなんてはっきりいえば、自業自得じゃ。きれいに負けてくれる事を祈る。

なんにせよ、これをよんでいる皆さん。選挙に行きましょう!

1998/07/08(Wed)

朝起きたら、母親の顔色が非常に悪い。母親が病院に行きたいというのだが、父親の姿が見えなかったので、とりあえず会社に休むからと連絡を入れて、車で行きつけの医者の所に行く。ひょっとすると、午前中だけで回復するかなぁと期待していたのだが、医者に行って帰ってくるだけで、お昼までかかってしまう。

母親は結局一日中寝込んでいた。それにつきそって、私もうちに閉じこもって、適当な時間潰しの本を読んでいるうちに1日が過ぎて行った。

1998/07/07(Tue)

M先輩から中古マシンを買う事になった。ところが、この中古マシン、壊れているんだよね。(^_^;どうにも動かないのでJunkマシンとして誰かに売りつけるつもりらしかったのだが、それを私が買い取ることになった訳だ。まあ、どこが壊れているにしても、最初から買いなおすよりもどこが壊れているか確かめてそこのパーツだけを取り替えればちゃんと動き出すだろうし、どうせLinuxとかX-Windowを動かす積もりなんで、そんなに最先端のスペックは必要ない。3台あれば本格的なネットワークシステムにおける分散プログラミングを実践できるから、それだけでも価値があるんだって言っているんだが、実は口だけで(^_^;、沢山マシンがあるとそれだけでなんだかうれしくなってしまうという貧乏性が現れたに過ぎない。(^_^;

今動かしているLinuxマシンなんて486 DX2改 Pentium 83Mhzなんだから、それの代替えマシンとして使うとか、それまでのLinuxマシンはMOとか低速HD管理用マシンとして使って、今度購入するマシンは比較的高速なXマシンとして使うという手があるから、それなりに使えるんじゃないかと感じている。まあいくら壊れているマシンでも、3万だったらJunk Partsの再利用だけでもそこそこ採算は取れるだろう。

やっぱり私はプログラミングというのを良く分かっていないんだろうな、と思う。関数のコメントの仕方で、どれがいいんだろうと悩む。悩んだのは以下の候補。


//バターン1

/*

Commnet: 関数fooの動作に関するコメント

Result : 関数の出力に関するコメント

  arg1 : 引数1に関するコメント

  arg2 : 引数2に関するコメント

*/

int foo(int arg1, int arg2)

{

//関数本体

}

以上が今まで私が書いてきた関数のコメントのパターン。でも、次のスタイルも捨てがたい。


//バターン2

/*

Commnet: 関数fooの動作に関するコメント

Result : 関数の出力に関するコメント

*/

int foo(

	int arg1,	//引数1に関するコメント

	int arg2	//引数2に関するコメント

)

{

//関数本体

}

次のパターンはパターン2とほとんど同じだが、関数1つあたり1行短くなるという魅力は、捨てがたいものがある。


//バターン3

/*

Commnet: 関数fooの動作に関するコメント

Result : 関数の出力に関するコメント

*/

int foo(

	int arg1,	//引数1に関するコメント

	int arg2	//引数2に関するコメント

) {

//関数本体

}

どうでもいいといえば、どうでもいいんだけど、どうでもいいからこそ、宗教的な熱意でこだわりたいという事もあって(^_^;、しばらく悩む。パターン1だとかなり複雑な動作をする関数も同一の形式で記述できるだろうけど、そもそも関数の動作とか引数をスパッと一言で説明できないようではそもそも初期設計が間違っているような気がする。感覚としては2が一番Fitするんだけど、貧乏性の私はより短い行数で同じことが表現できる3のパターンにも魅力を感じる。結局前任者のソースが2のパターンだったので、当面それを採用する事にするが、3のパターンも(ほんのちょっとの違いとはいえ)捨てがたいなぁ。<単に貧乏性なだけか?(^_^;

前の前の職場(もう3年前になる)で書いたプログラムについてH氏が質問をしてきた。そのプログラムはWindows DLLを最初に作った時のヤツで、今考えると赤面モノのプログラムだわ、ドキュメントは全然作っていないわで、引き継いだ人はいつでも私にケリを入れていいという感じのプログラムだったのだが(我ながら情けない出来だった…)、そいつをMacに移植しているんだという。あれ、Macの事はよく知らないけど、あのプログラムを別のプラットフォームに移植するくらいだったら、最初から書き直したほうがいいかもしれない。(^_^;(事実、実質的に書き直しになっているらしい。)

一応、憶えている限りでの一通りの説明をしたら、むこうが勝手に納得してくれたみたいで安心した。まあ、こっちはMacのことはさっぱり分かんないので、アドバイスしたくても出来ないんだけどね。がむばってください>H氏。

Visual C/C++5.0向けのちょっとしたマクロを組んでみる。C/C++ユーザーじゃなければそんなに意味がないだろうVBScriptだけれど。ライセンスとか、動作条件とか書いているうちにあっという間に時間が過ぎる。公開は明日以降だな。ちなみにサンプル程度の小さいマクロなので期待しないように。(^_^;

そういえばNetworkを通じてクリップボードを共有するツールもいい加減、何とかしないとね。

1998/07/06(Mon)

アルゼンチン、あそこでGKにヘッドバットを食らわせて、退場者を出すかねぇ。で、退場者を出した直後に決勝点を入れられて負けているし。なんかすっきりしない負け方だなぁ。

Make Money Fast系統の記事がfjにあった。fjに流している記事なのに、極秘なんだそうな。私にはとても理解できない言葉遣いだ。(^_^ちなみにMessage-ID: <6nhpkk$kdi$3@news2.dti.ne.jp>

本社総務課からe-mailで連絡が入る。


出張時に提出頂いています「出張届 出張報告書」につきまして、

下記のとうり記入して頂きますようお願いします。

よっぽど「『とうり』って?」とreplyしようと思ったのだが(^_^;、さすがにそんな洒落が通じる相手か分からない。(^_^;

1998/07/05(Sun)

自宅のサブマシンを起動したら、Linuxはちゃんと起動するのだが、Windows95が全然駄目。OS Bootまではいくのだが、何かアプリケーションを起動するとマウスポインタごとフリーズしてしまう。不思議なのは画面がフリーズしているにもかかわらず、その他の昨日は生きているらしい事。外部からPINGを打つとちゃんと返ってくるし、キーボード操作(ALT+F4)ではちゃんとシステムをシャットダウンできる。訳がわからない。まあ、Windows95なんてこのマシンで動かなくてもいいんだが、動かないとなると気になる。システムをいじるといってもこのマシンはほとんどdefaultのままだしなぁ。困った。

OSの上書きインストールでも駄目だったので、仕方がないのでまっさらからインストールを決意。どうせこのマシンのWindowsパーティションにはほとんど重要なデータを置いていなかったし、あらかたのプログラムはもう一台のマシンにコピーがあるし、この2台はちゃんとethernetで繋がっているから、復旧作業は大したことがないと踏んでいた。

ところがレスキューディスクから起動するとバックアップ様に用意しておいたMOが全然読めなくて面食らう。今までバックアップしておいた奴があらかた読めないと分かった時には、本当にパニックになった。こんなのどうやってもとのMOのデータも含めて復旧すればいいんだ!

とりあえず、Linuxを起動してMOを読んで見ると、何とか日本語ファイル名を使っているもの以外は何とか読めるみたい。まあ、日本語ファイル名を使っているヤツは(私が作った奴じゃないのは確実だから)後でどこかから入手できそうだというので、適当にバックアップを取り始める。う〜む、最後の手段はLinuxだったのか。(^_^;教訓。「データを最後に救うのはWindows95レスキューディスクではない。共存しているLinuxである。」

幸い、もう一度Windows95をインストールしなおしたら、読めなかったMOも読めるようになった。これって一体何?(^_^;

この作業に伴なって、MOのデータを整理もしていたら、1日終ってしまった。

自宅のHUBが壊れた。電源を入れてもPower/OnマークがつかないのでAC Adapterがらみかな?と思ったが、代わりのAc Adapterがないのでハブごとかって来てしまう。(といっても5000円ほどだが)代わりのハブに付属のACアダプタをつけても元のハブは死んでいる。どうやら元のハブが死んでいるようだ。買い替えて正解である。しかし、安物のハブだとこれしきしか持たないものなんだ。高々1年程度電源常時On状態にしておいただけなのに。まあ、安物だったから仕方がないか。保証期間が切れた頃に故障が起こったのは偶然だろう。

1998/07/04(Sat)

1日、本を読んで過ごす。既読の本を本棚から引っ張り出して何冊か読んだ。こんなのって、何かやりたいとかやらなくちゃいけない事が間近に控えている時の、典型的な行動パターンなのだが(^_^;、今の所そんな事もないしなぁ。まあ、でも他にもゲームをやったりとかのんびり過ごした1日だった。

1998/07/03(Fri)

馬鹿をやったので、死にたくなった。こんなのCの初心者でもやんないぞっていうミス。で、ミスをすることは全然珍しくないのだが(^_^;、ちゃんと自分で一次検証していれば指摘されるまでもなく気がつきそうな所だったので、もう穴があったら入りたい気分だった。ほんと、こいつは一回死んだほうがいいかも。

ミスの状況は次の通り。辞書ファイルのヘッダーを書くルーチンの一部。辞書ヘッダーの場合にはオフセットと全体のサイズはドキュメントで定められているが、ヘッダーに入っている個々のデータのサイズは違っていることが多い。今回の場合は、それでも比較的単純な方で、単にWORDデータと固定長文字列が混在しているパターンだった。

こんな場合の定番は


#define OFFSET_PARAMETER1 (0)

#define OFFSET_PARAMETER2 (2)

(以下延々続く)

とかやって、本体部分では例えば、


char szHeaer[HEADER_SIZE];

*(WORD *)(szHeader + OFFSET_PARAMETER1) = (WORD)なにかのパラメータ1

*(WORD *)(szHeader + OFFSET_PARAMETER2) = (WORD)なにかのパラメータ2

(以下延々続く)

というのが普通。で、普通なんだから、これでやればいいものを、なんかこれだとキャストが沢山あって嫌だなぁと(その時の私は)思ったらしい。という訳でこんなコードを書いた。


char	szHeaer[HEADER_SIZE];

LPWORD	pWord = (LPWORD)szHeader;

*(pWord + OFFSET_PARAMETER1) = (WORD)なにかのパラメータ1

*(pWord + OFFSET_PARAMETER2) = (WORD)なにかのパラメータ2

(以下延々続く)

これ、考えてみると、というか考えてみるまでもなく、全然違うコードになっている。なんでこんな間違いをしたんだろう?情けない。ちなみにこの違いって、Cの初心者でも分かる程度の違いなので、解説はしません。(情けなくて出来ないというのもある。(-_-;;))まあこのページの読者はほとんどプログラマーみたいだから、私がどんなあほうな勘違いをしたってのは、分かるでしょ?

いや、私もね、OFFSET_PARAMETER2なんてパ多メータを導入した時から、szHeaderへのオフセット指定には、「OFFSET_PARAMETER2/sizeof(WORD)」位には芸を使わないといけないと思っていたんだ。ところが別の事を考えていたら、スコーンと忘れちゃったんだよね。(T_T

先月読んでいたプログラムがやたらとキャストしまくりのプログラムだったのでWORD *をWORD *にalmost everywhereでcastしていたのは驚いた。一体何の意味があるのだ?)、ますますキャストが大嫌いになってしまったせいかも。

でも恥ずかしい間違いだよなぁ…。(_ _;;

1998/07/02(Thu)

コーディングの続き。コーディングも残り少ないだろうからコーディング自体は1時間程度で終るな、と思って書いた。残っているコーディング部分は、既存の辞書からレコードを全て読み込んで、現在メモリにあるレコードとマージし、新しい辞書ファイルを作るという部分だ。まあIME辞書の単語一括登録みたいなツールだと思えばいい。

基本的な戦略は、一旦既存辞書の全部のレコード内容を示すオブジェクトを発生させておいてから、既にメモリ上にある新規レコードオブジェクトとマージして(CObArrayを使っているから、簡単)、それを新規辞書のレコード群だと思ってファイルに出力する。メモリの使い方としてはものすごく贅沢なやり方だけど、どうせ辞書ファイルのサイズが1Mないので、こんな一見無茶なメモリの使い方でも何とか動く。

もちろん、データサイズが巨大になったら、そのデータ構造はかなり見直さないといけないかもしれないというのは分かっている。ただ、辞書ファイルが早々巨大になるとも思えない、巨大になったらなったでFile I/Oで時間がかかっちゃうからどうでもいいんだという話もある、そもそも瞬間的に最大でも数メガ程度のオブジェクト群を生成するだけだから、これをユーザーに公開するとしてもそんなに不都合はないだろう。まあ、User I/Fは欠陥だらけだが。(^_^;

で、このメモリ上に全部オブジェクトを置いて…という戦略でやっていたら、追加コードが20行ほどで済んだ。で、20行ほどで済んだのは良かったのだが、例外処理もちゃんとやろうと欲が出てTRY CATCHとか使い始めて泥沼。で、20分ほどはまっていたのだが、END_CATCHを書き忘れていてはまっていたというおそまつ。大馬鹿である。

今日debugしていて、一番はまったのが、CArchive::ReadString()。途中で例外が起きるのだが、ちゃんとプログラムは動いているっぽい。じゃあ、何で例外が起きるのかと調べてみると、EOFを超えた辺りで例外が起きていることが分かる。まあ、一般保護エラーじゃないし、ちゃんとプログラムが動くので気にしなくても…と思ったが、何か気になって調べてみた。私の書いたコードはどう考えても何かエラーが出るコードじゃないようなぁ。じゃあ、MFCのソースまで追いかけてみようと思って、MFCの内部までトレースしてみたら、CArchive::ReadString()はEOFにぶち当たると必ず例外を投げるということが分かった。バグじゃないと分かって安心するというか、そんなまぎらわしい例外を投げないで欲しいというか…。例外処理って、そんな風に使うものなのかなぁ。なんか例外処理ってメモリが足りなくなったとか、Disk Fullとかという状況の回復に使うんだって思っていたけど…。

上司のNさんと先輩のIさんの仕事が大変な事になっているらしい。私は全然タッチしていないので、よく分からないのだが、共同作業している会社が台湾の会社で、メールやら電話で色々やり取りをしているらしいのだが、むこうは英語らしくて、そこら辺のCommunication gapもネックになっているらしくていらいらしているのが分かる。

こんな時は、おとなしく仕事をして目立たないようにしているのが最善の策なんだが(^_^;、ちゃんと「この前確認してくれって言ったバグレポートってどうなってる?」とこっちの痛い所を突いてくる。中途半端にしかやっていない事を正直に言っておく。もっとも今書いているプログラムがある程度まともに動いているようだったら、そちらに取り掛かるつもりだったのだが、今日までの作業である程度使えそうなモノが出来たので明日はそのバグレポートの確認に費やすつもり。ただ、「人の使い方」というのを見たような気がした。

参議院選挙の政見放送。昔は雑民党とか、UFO党とか、ぶっ飛んだ党がいて見るのが楽しみだったのだが(^_^;、最近はそんなぶっ飛んだ党がないのね。昔とちょっと選挙制度が変わったせいだろうけど、比例代表の選挙としては昔のほうが面白かったような気がする。ただし、政見放送で党首や候補者のいっている事を分析するのもいとをかし。ただし、まともに見た訳じゃない。

自民党。例えば橋本総理が「教育に力を注ぎます」だとかいっても、どう変えて行くのかってのが全然見えてこない。お前ら政権党にいたんだから、力を注ぐって強調する以上、今迄以上に予算とか手間暇をかけるって意味だと解釈してもいいんだよね。で、この前の選挙のときもそんな事を言っていた気もするんだけど、どんな成果が上がったのだろう?サカキバラ君の事件が成果だっていうつもりなのかな?

共産党。書記長が「大手ゼネコンだけを儲けさせるような公共事業を止めよう」と言っているけど、別の候補者は「建設業の雇用を確保しよう」といっている。建設系公共事業が減る→仕事の絶対量が減る→雇用が確保できなくなる or 賃金が安くなるなんて中学生でも分かる理屈だと思うんだが。

自由連合。消費税をなくしましょう→減税になるから消費が増える→経済が活性化するという図式にはそんなに異論がない。ところで、経済が活性化したのはいいけど、今の膨大な財政赤字ってどうするつもりなんだろう?減税→経済が活性化→企業収益が上昇→減税分を補う税収が得られるなんて図式があるなんてのは大間違いだし、つい10年ほど前にその大間違いのせいで大失敗した某国を、医者っていうインテリに属する人達だったら知っていて当然のはずなのに。

いちおう解説すると、その大失敗した国ってのはアメリカの事で、それを推進した大統領はレーガン。減税する→経済が活性化する→企業収益→減税分を上回る税収アップというのがレーガノミックスの骨子なんだ(と聞いている)けど、決して減税分を上回る税収アップにはならないってのは、レーガン大統領退任時のアメリカ財政赤字と今のアメリカ財政赤字を比べてみるだけでいい。

あと、やって欲しいのが公約の○×表。前回、この政党とか候補者はこんな公約を掲げたけど、出来たのに○、出来なかったのに×とか付けてもらうといいんだけど。○が一つもなくて比較にならないって記事でもいいから出して欲しいなぁ。

1998/07/01(Wed)

自分の書いたプログラムをざっと概観してみて。まあ、データファイルが高々1M位のものだから、一気にメモリに展開しているし、別形式にセーブする時も一旦セーブするレコードを全部目盛りに書いてからファイルに落としているから、コーディングは楽だが、すごいメモリの無駄使い。これはストレステストをしたら、一発でアウトのパターンだな。(^_^;

でもまあ、メモリの無駄使いは仮想記憶のマジックが何とかしてくれるし、画面を更新する度にFile I/Oが入ってきたんじゃ遅くなるだろうし、高速化するためにはメモリを湯水のように使うか、アルゴリズムを書き換えるしかない。そこまでしなくてもいいか。所詮社内で使うツールだし。

コーディングはそこそこ順調って所だろうか。残す所はあとわずか。今日中にコーディングを終らせようとも考えた。残っている部分はファイルから固定長のレコードを読み込んで、そのレコードの内容に従ってオブジェクトを発生させる所だけで、さらっと書けば30分程度で済むような所だとは思った。しかし、もう勤務を開始してから8時間を超えているし、書くのが30分でも書き終わったら少しくらいは動かしてみたくなるし、動かしてみたらdebugしたくなるし…というのが見えていたので、思い切って切り上げる。

コーディングをしながらも、ある程度まとまった(といっても100行とか200行位だが)機能を書いたら、私の場合にはコンパイルと大雑把なデバッグ(まともな入力に対して、まともにある程度まともに反応するかといった程度)をしてみることにしている。私はキータイプが得意な方ではないので、変数名とかはしょっちゅう打ち間違える。だから、1000行以上書き上げてから初めてコンパイルするとなると、100個以上エラーが出ちゃって打ち間違えを訂正するだけでも嫌になっちゃうんだよね。(^_^;で、ある程度まともな入力に対してまともな反応を確かめられる小さい単位でデバッグするのは、まともな入力に対してまともな入力を返せないような小さい単位が集まって、大きなプログラムが全然まともな出力をしないとなると、飽きっぽい私は「こんなもの書き直しちゃえ」となるんだよね。(^_^;書いてすぐだったら直しやすいし。

本当だったら、今回やったみたいに場当たり的にクラス設計をガシガシ変えちゃうようなやり方はまずいんだろうし、基本設計から時間をかけるのが本道なんだろう。大きなプログラムだったら、それなしでやったらパニックになるのは目に見えているのだけど、今回のは小さなプログラム(多分全部で5000行以下、今日の朝数えたら、3000行弱だったから、全体で4000行行かないかも。)だし、一人で書いているからまあそこまでしなくてもいいんじゃないかと思っている。

ところで、先週の月曜日の午後から始めて今の今までなぜ3000行しか書けないのかとか、この程度のプログラムになんでこんなに時間がかかっているんだというのは、禁断の疑問なので思っていても口に出してはいけません。口に出した人は呪われます。(キッパリ)

最近Sさんから「いやぁ、こんなこといっちゃうとまた日記に書かれちゃうかなぁ(笑)」と言われることが多くなっている。やっぱりこれって書いて欲しいってことなんだろうな。だったらネタを提供して下さい。(笑)>Sさん


1998/6 後半のぶつぶつ

1998/7 後半のぶつぶつ

日々のつぶやき 目次

作者(vyama_at_janis_dot_or_dot_jp)への感想・意見など。
spamよけのため、_at_や_dot_は適宜@や.に入れ替えてください。

目次ページ