マクロを速くする方法はありませんかNo.03003
タナカ さん 02/02/18 00:05
 
みなさん今日は。タナカと申します。
 「行単位でソート」したくてマクロを探してみた所、秀丸サイトのマクロライブラ
リに塚本 牧生さんが作ったマクロがありました。でもソースを読んでみたら「バブ
ルソート」アルゴリズムでなかった為、自分でバブルソートするマクロを以下のよう
に作ってみました。
 しかし、塚本 牧生さんのに比べて少し遅いようです。手元に180行で7.3kBのデー
タがあるのですが。
塚本 牧生さんの → 7秒ぐらい
私の       → 10秒ぐらい
の差があります。何故でしょうか。
 他にも秀丸マクロ独自の動作速度を速める工夫ってありますでしょうか。
//----------------------------------------------------------
//##1:開始行、##2:終了行、##3:降順フラグ(昇順→0、降順→1)
SortLines:
    ##StartLine = ##1;
    ##EndLine = ##2;
    ##AsReverse = ##3;
   
    $$Line1 = "";
    $$Line2 = "";
   
    ##i = ##StartLine;
    ##j = 0;
    ##k = 0;
    ##m = 0;
   
    $$Title = "ソートしてます:";
    $$DispTitle = "";
   
    disabledraw;
    disableinvert;
    disablebreak;
    while (##i < ##EndLine) {
        ##k = 5 * (##i * 3 / 2) / ##EndLine + 1;
        ##m = 0;
        $$DispTitle = $$Title;
        while (##m < ##k && ##m < 5) {
            $$DispTitle = $$DispTitle + "■";
            ##m = ##m + 1;
        }
        while (##m < 5) {
            $$DispTitle = $$DispTitle + "□";
            ##m = ##m + 1;
        }
        title $$DispTitle;
       
        ##j = ##EndLine;
       
        movetolineno 1, ##j;
        selectline;
        $$Line1 = gettext(seltopx, seltopy, selendx, selendy);
       
        while (##j > ##i) {
            movetolineno 1, ##j - 1;
            selectline;
            $$Line2 = gettext(seltopx, seltopy, selendx, selendy);
           
            //昇順で前の行が大きいとき
            //降順で後ろの行が大きいとき
            if ((##AsReverse == 0 && $$Line2 > $$Line1)
                    || (##AsReverse == 1 && $$Line2 < $$Line1)) {
                movetolineno 1, ##j;
                beginsel;
                golineend2;
                right;
                cut;
               
                movetolineno 1, ##j - 1;
                paste;
            } else {
                $$Line1 = $$Line2;
            }
           
            ##j = ##j - 1;
        }
       
        ##i = ##i + 1;
    }
    enabledraw;
    enableinvert;
    return;
//----------------------------------------------------------

[ ]
RE:03003 マクロを速くする方法はありませNo.03004
アルビレオ さん 02/02/18 11:25
 
>何故でしょうか。

バブルソートだからです。

バブルソートは数あるソートアルゴリズムの中でももっとも遅いものと
いうのが一般的な認識だと思ったのですが、なぜわざわざバブルソートに
書き直したのでしょうか?

> 他にも秀丸マクロ独自の動作速度を速める工夫ってありますでしょうか。

ソートする量などにもよりますが、普通はソートアルゴリズムの違いが
もっとも大きく影響すると思います。

というか、速度が必要ならマクロだけでやろうとせずにSORT.EXEなどの
外部プログラムを使った方が圧倒的に高速です。

[ ]
RE:03003 マクロを速くする方法はありませNo.03005
ひろ さん 02/02/18 12:34
 
 タナカさん今日は、ひろです。
>  しかし、塚本 牧生さんのに比べて少し遅いようです。手元に180行で7.3kBのデー
> タがあるのですが。
> 塚本 牧生さんの → 7秒ぐらい
> 私の       → 10秒ぐらい
> の差があります。何故でしょうか。
 塚本さんのマクロのアルゴリズムが解らないので、明確には言えませんが、
たった一つのデータで速度比較をしても無意味です。ソートのアルゴリズム
はそれぞれ元のデータによって速度が変化します。要は得手不得手がありま
す。そもそもバブルソートって、高速だったかな?

>  他にも秀丸マクロ独自の動作速度を速める工夫ってありますでしょうか。
(1)メンテナンスを考えなければ、まず call や goto を使うのを止める
(2)不必要な変数を削除します。例えばおそらくここでの
> //##1:開始行、##2:終了行
とは、範囲選択した部分だと思うので、範囲選択したままにして置けば、引
数は必要なくなります。
>     $$Title = "ソートしてます:";
 この変数も
        $$DispTitle = "ソートしてます:";
とすればいらないですよね。
(3)
>     disabledraw;
これはマクロの最初に 1 回
>     enabledraw;
をマクロの最後に 1 回にした方がよいです。
(4)外部プログラムを使う
>  「行単位でソート」したくて
ということなら、
disabledraw;
run "sort < con > con";
enabledraw;
の要領です。AMD-K6II 400MHz, 256MB の環境で、660 行、262 KB、のデータ
で 10 秒程度です。

[ ]
RE:03003 マクロを速くする方法はありませNo.03006
安久津 さん 02/02/18 18:34
 
安久津です。
秀丸だけでやるなら以下。
// ------------------------------
// 塚本さんの sort.mac のクリップボードをキューちゃんにする方法を利用。
// アルゴリズムを2分挿入法にした。
    if( ! selecting ){ beep; endmacro; }
    else if( (seltopx + selendx)!= 0 ){ beep; endmacro; }
    disabledraw;
//  $END = " / " + str(selendy); // 論理行でないが。(^^;)
    cut;
    ##first = lineno; ##last = lineno;
    escape; movetolineno 1, ##first; insert "\n";
    beginclipboardread;
    $$cmp = getclipboard; // + 0x0a
    while( $$cmp != "" ){
        ##low = ##first; ##high = ##last;
        while( ##low <= ##high ){
            ##mid = (##low + ##high) / 2;
            movetolineno 1, ##mid; beginsel; golineend2;
            if( $$cmp > gettext(seltopx,seltopy,selendx,selendy) ) ##low = #
#mid + 1;
            else ##high = ##mid - 1;
        }
        escape;
     if( $$cmp > gettext(seltopx,seltopy,selendx,selendy) ) movetolineno 1,
lineno + 1;
        else golinetop2;
        insert $$cmp; // + 0x0a
        ##last = ##last + 1;
        // if( tickcount > #TICK ){ title str(##last)+$END; #TICK = tickcoun
t + 2000; }
        $$cmp = getclipboard;
    }
    movetolineno 1, ##first; delete;
endmacro;
// ------------------------------
// 注意事項。
// もし被ソートデータの行末に 0x0a 未満の制御コードが存在する場合
// 正しいソートができない。例は水平タブ。
// 本来 "AA\x09" > "AA" です。
// しかし、クリップボードから "AA" を取得すると、末尾に \x0a が付いてきます。
// んで、"AA\x09" < "AA\x0a" になります。

では。
#メインエディタが vim になっちゃいました。(^^;ゞ

[ ]
RE:03003 マクロを速くする方法はありませNo.03010
タナカ さん 02/02/21 01:40
 
 アルビレオさん、ひろさん、安久津さん、レスありがとうございます。
まとめてで申し訳ないですがお礼を申し上げます。

アルビレオさん
>バブルソートは数あるソートアルゴリズムの中でももっとも遅いものと
>いうのが一般的な認識だと思ったのですが、なぜわざわざバブルソートに
>書き直したのでしょうか?
 塚本さんの作ったものが、バブルソートと称しているのに、バブルソートになって
なかったからです(挿入ソートでした)。秀丸マクロをやり始めて未だ日が浅いので、
慣れようと思ったのです。
 で、処理の数(比較など)は、ほぼ同じはずなのに、何で体感できるほど、速さが違
うのかと思った次第です。


ひろさん
>(4)外部プログラムを使う
>>  「行単位でソート」したくて
>ということなら、
>disabledraw;
>run "sort < con > con";
>enabledraw;
これで特定の範囲をソートする方法はあるのでしょうか?

安久津さん
>// アルゴリズムを2分挿入法にした。
わざわざありがとうございます。

[ ]