jsmodeに「非同期」メソッド追加のお願いNo.11226
western さん 23/04/15 11:36
 
jsmode の「非同期」で使えるメソッドとして
「選択範囲の『座標』」を取得できるものを追加して頂けませんでしょうか?

選択範囲のテキストを取得するメソッド(getSelectedText)は見つけたのですが
範囲の4つ(+α)の値を取るために postExecMacroMemory("") を使っていたところ
4つの値だけで 1.6ms (1値あたり 0.4ms @ 4.2 GHz PC) かかっていたのがわかり、
たまにキーボード操作のコマンドが漏れたり、マウスで操作した際に、
マクロ止める? メッセージ(抑止してない状態) やカーソル移動のモタつき
が気になる程度の操作感となってしまいました

以下の4値を常にセットで使うので1つのメソッドになるかと思います
が、今の秀丸エディタは複数個所の同時選択ができるので、その時は
その数だけ返り値が4つずつ伸びるようにするのが、
LSPのマルチカーソル想定と相性がよいかもしれません

[seltoplineno, seltop_wcs, selendlineno, selend_wcs, ...multi] = hidemaru.ge
tSelectedRange("wcs");


それと、LSPにはRange指定コマンドがいくつかあり、描画範囲(画面の上端と下端の行)
の取得ができれば、色付け範囲を指定したコスト削減などにも使えるのですが
ワープロ的な screentopy と windowheight (これは計算時に最大でも、の値として
は使える)
ではLSP相手のRange指定にキッチリとは使えないので、

results.screentopy = hidemaruGlobal.screentopy();
results.ytolineno0 = hidemaruGlobal.ytolineno(0, results.screentopy);
results.yendlineno = results.ytolineno0 + hidemaruGlobal.windowheight();

と3つの hidemaruGlobal コマンドを実行して 0.4ms * 3 = 1.2ms くらいかかります

こちらも [toplineno, endlineno] = hidemaru.getScreenRange();
のような非同期メソッドがあると副作用回避しながらコストも削減できます
// left と right の値は使い処があるかどうか不明ですがセット的に4つになる?


これらはオンデマンドで取得したり、値をキャッシュするロジックにすれば支障は減
らせるので
特に急ぎではないので、ご検討だけでもよろしくお願いします


参考の計測 (CPU 4.2 GHz)

// 非同期メソッド1つでカーソル座標2値取得 0.2ms くらい
[lineno, column_wcs] = hidemaru.getCursorPos('wcs');

// 同期メソッド2つでそれぞれ取得 0.8ms くらい (0.4ms * 2)
results.lineno = hidemaruGlobal.lineno();
results.column_wcs = hidemaruGlobal.column_wcs();

// 0.4 * 150 => 55ms くらい (外部メソッドをコールする invoke 処理共通の事情
だと思います)
hidemaruGlobal. で取れる内部的な値を表現するキーワード150種を列挙して取得

// それ以外の postExecMacroMemory な処理
hidemaruGlobal を使わない普通のロジックを組む分には、
パフォーマンスカウンタの最低分解能の 0.1ms を超えずに処理できました


[ ]
RE:11226 jsmodeに「非同期」メソッド追加No.11227
こみやんま さん 23/04/15 12:34
 
hidemaruGlobalにあるものは全部 javascript ⇒ eval ⇒ 秀丸マクロ文法として実
行 ⇒ 結果 ⇒ javascript という手順が踏まれているので

「秀丸マクロ」で記述しているよりさらに遅いんですよねー

将来的には evalをやめて private なネイティブ関数への参照という形に差し替えて
いかないと、
全体的にパフォーマンスは出ませんねぇ。
(将来的にはネイティブ関数への参照にしたい的な担当さんの投稿はあったはず..)

[ ]
RE:11227 jsmodeに「非同期」メソッド追加No.11228
western さん 23/04/15 13:56
 
一時変数を使う
hidemaru.setStaticVariable() → getstaticvariable()
hidemaru.getStaticVariable() ← setstaticvariable
を値の受け渡し経路にして

postExecMacroMemory の中で "js{ hidemaruGlobal.xxx }"
を介さずに、中身を従来の秀丸マクロで完結させてしまえば、
現状の実装としてパフォーマンスは改善する仕組みなのでしょうか

そうであれば postExecMacroMemory 部分をミニマムな
従来の秀丸マクロに置き換えてしまうのは問題ないです


今回は WebView に組み込みのパフォーマンスカウンタが使えたので
気になった原因として調べることができたというだけの話です
従来の秀丸マクロを使ったパターンの計測方法が分からないので
ベンチマークやプロファイル試せていません


あと、仕様の確認なのですが

コンパイル済み秀丸マクロのメモリ上へのキャッシュとその実行として
postExecMacroMemory からガンガン使うパターンで有効に働く
組み方がある、想定されているのでしょうか?

[ ]
RE:11228 jsmodeに「非同期」メソッド追加No.11229
western さん 23/04/15 19:29
 
推測するな、計測しろ! の鉄則をふと思い出したので
パフォーマンスカウンタDLLを作って postExecMacroMemory 内の秀丸マクロで loadd
ll させて測定しました

■ 従来の秀丸マクロで値を取得して9つの setstaticvariable で共有

・カーソル位置の2値     [0.002ms]
・選択範囲の4値       [0.015ms]
・画面の上端行と画面内の行数 [0.007ms]
・hidemaru.getStaticVariable で上記9値の読み取り 1.2ms

■ 従来の秀丸マクロで値を取得して1つの setstaticvariable で共有 (join と sp
lit)

・上記値9つの取得のみ(上記は setstaticvariable 含む) [0.015ms]
・9つの数値を連結して setstaticvariable で共有    [0.012〜0.015 ms] (+
連結とsprintfは大体同じ)
・連結した値を hidemaru.getStaticVariable で1つ取得  [0.2ms] (js で分解す
る処理含む)

という結果になりました

結論:
・従来の秀丸マクロでやる方が100倍くらい早い
・hidemaru.getStaticVariable を9回呼ぶより1回だけで済ませれば 1.0ms 縮む
・それを実現するための手間をかける価値は巨大

[ ]
RE:11229 jsmodeに「非同期」メソッド追加No.11231
秀丸担当 さん 23/04/17 10:59
 
hidemaruGlobalにあるメソッドは、マクロとしてevalしているものがほとんどで、一
文一文はパフォーマンスが悪いです。
特定のめぼしいものはネイティブ的に直接呼んでいるものもあります。
それと気づかないうちにネイティブにすり替えていったりしています。

[ ]