Note

サイト
最近のコメント
 | 

2004-05-30

[][] いただいた不具合報告から

Windows2000ではゴミ箱をデスクトップから消しているとSHSpecialFolderLocationで取得ができなくなるらしい。

(というより本来非表示にできないものを、レジストリを消すとかして取得をできなくすることで非表示にしてるんでしょうね。その手のツールはよく知りませんけど)

その状態ではEOFileも起動できなくなります。

[] 今まで気付かなかった私

全ページにアクセス解析でも仕掛けない限り反応し切れないのはわかりきってたことですが、とにかく見落としてました。

http://user.ecc.u-tokyo.ac.jp/~s31552/wp/misc/index.html?2003082704#2003082704

で…

「単位解析」って何のことだろうと思ってたら。

…単位解析ってAdaにあったっけ?
…そもそもAdaは [ ] も { } も使わないような?*1

推測ですが、単位解析がAdaの文法にあるとしても、特定コンパイラの独自拡張としても、BASICの"^"じゃなくてAdaの"**"演算子が使われると思うんですよね。人様の勘違いを前提にするのはいけないことですが、おそらく、その部分のソースコードはAdaじゃ無くPascalだったのではないでしょうか?Pascalですと { } がコメントなので辻褄はあうんです。その場合type FLOAT = Real;なんてまた面倒なことしてやがるって事になりますが。RealじゃなくFLOATって事はやはりAda?その場合にしても、単位解析がある、よりも、Pascal風に { } でコメントが書けるAdaコンパイラがある、のほうが、もっともらしく思えてしまいます…。

私に言えるのはAdaの規格の変数宣言だか浮動小数点型の定義だかを斜め読みしても単位解析っぽい機能は無さそうだなあ、ぐらいのものですが…。

で…

別にshinichiro.hさんだけに言うんじゃ無いんですが、標準とか通常とか誤解がありそうですので…推測だけで言うとおそらく"Standard"パッケージの事と思うんですよね。"Standard"って名前です。DelphiのSystemユニット、Dのobjectモジュール同様、Adaは"Standard"パッケージが暗黙に使われますので。

Integerをパッケージ名から全部書き下すとStandard.Integer、といった具合です。System.Textとかobject.Objectとかと同じで。

[] えーと。

OK, J・J*2, 遅いのはバッファのせいじゃなさそうだ。それは認めよう。未知のバッファ構造に触れて私が興奮していたのは事実だし、それで多少は意味不明な事を書いて恥をさらしたのも認めるのにやぶさかでは無いよ。

だがちょっと待ってくれ。じゃあ、何が遅いんだ?

色分けロジックが致命的に遅いのは承知している。だが、これは最初こそ遅いが一旦最後まで色分けが済んでしまうと、後は差分だけの処理だ。Windows.pasを開いて、最後までスクロールしてみたまえ。初回はイライラさせられるが、二回目以降はスムーズだ。感動的だね。途中を編集したって、色分けを再計算するのは前後の数行でしかない。

それで疑問となる。じゃあ、何が遅いんだ?

OutputString(PChar(IntToStr(GetTickCount)))というあまり精度のよくなさげというよりお粗末な式を埋めこんで測定しましたところ、一文字の挿入が0.020秒程度ならスムーズに処理され、0.030秒程度なら多少表示が引っかかるものの待たされはしないようです。恐らくこの0.010秒の差が、WM_PAINTのタイミングを奪ってるんでしょう。もちろんGetTickCountは0.001秒単位で取得はできますが精度はもっと悪いのは承知の上──。

で、現象としては、ファイルの末尾に近づくほど高速に編集できます。前の方ほど待たされます。4MBのファイルの先頭部分なんか、0.060秒もかかってます。

で、結果から書きますと…バッファとは別に、行の管理情報が双方向リンクリストになっているわけです。そこには、その行が先頭から何バイト目からはじまっているかが、32ビット整数として記録されています。一文字挿入したら、現在キャレットがある行以降の全てに対して、リンクリストを辿ってそのデータフィールドに+1して回らなければなりません。

4MBのファイルは行にして27万行近くあります。

以下の処理を27万回繰り返すのが、時間のほとんどを食っていた、というわけです。

add TLine[eax].Position, edx
mov eax, TLine[eax].Succ;
test eax, eax
jnz @loop

GreenPad…普通のエディタでも同じですが、一度引用した縁で今回も引用させてください…では、一文字挿入では以降の行を更新する必要はありません。というよりソース見て驚いたのですが、行が行番号等の全文書中の位置を示す情報を全く持っていないため、その手の必要は全く無いのです。

Thebeでは愚かにも、行は、開始バイト位置と、行番号というふたつの、文書中の位置を示す情報を格納しています。故に…遅くなるのです。

Q.E.D.

…って行番号は工夫すれば取り除けますけど、開始バイト位置は…行が実際のデータを持てるならまだしも、ひとつのバッファを複数のビューが、しかも異なるエンコーディングや表示形式で共有するがために、各「行」にバッファ内の位置を示す何らかのポインタが必要な訳で…

OK, J・J. そのバッファもまた単方向リンクリストだ。前の方に挿入/削除を行っても後ろの方に被害は無い。バイト位置だから毎回更新が必要になるのであって、各細切れ要素へのポインタ+その細切れ要素内での位置、という構造なら、無関係でいられる場所が増えるかも知れない。

…しかし…ビューは複数あるんですよ?矛盾無く整合性を保てるのか…は私の技量次第なんですが、今更そんな大規模な変更を!?

やだー

*1:使うってば http://www.adaic.org/standards/95lrm/html/RM-2-1.html …でも実際どこに使われているかは不明

*2エラリー・クイーンの国名シリーズに出てくる「聞き手」

shinichiro_hshinichiro_h 2004/05/31 16:12 あー…明日件の本を確認してみますです。

 | 
カレンダー
2004 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2005 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2006 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2007 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2008 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2009 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2010 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2011 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2012 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2013 | 01 | 02 | 03 |
Connection: close