配列のソートNo.01565
山紫水明 さん 00/10/29 09:05
 
  こんにちは,山紫水明です!

 $data[#n] の配列があります。(#n はさしあたり 100 程度)
 これをソートするマクロを作りたいのですが,方法ご存じの方教えてください。
 一つ一つ比較して力ずくでやっていけばできるのですが,何かもっと効率的な方
法があると以前に何かで見たような気がしますが,手許に見つかりませんので。


[ ]
RE:01565 配列のソートNo.01566
encodingshiftjis さん 00/10/29 13:53
 
> $data[#n] の配列があります。(#n はさしあたり 100 程度)
> これをソートするマクロを作りたいのですが,方法ご存じの方教えて

研究され尽くされた分野なので、変なのを出すのはちょっと気おくれ
事前に考える事項は多い
▲大小比較は何を使うか?
秀丸マクロの文字列比較の詳細は? 例 "A" "a"  'A' 'a' 漢字記号 など
音引き や 幼促音を考慮する「国語辞典順」をするのか
大文字小文字全角半角平仮名カタカナ..  記号は無視 ...
▲処理の形態
全面新規ソート 対 ソート済み配列に要素の追加か
重複キーは多いか少ないか
ソース順の保存は必要か?(同一キーの時)アルゴリズムによっては
原始配列を保存しないソートになる。
ソート前後のサービス処理も考えるか?
ソート対象にしない物が混在するか、重複キーは単一化するか
▲実現の形
秀丸マクロで作る
DLL を書いて WinのAPI 等を呼び出す

すぐ出来るのは
新面を開いて、配列を書き出し、SORTコマンド実行の結果を
結果を配列に戻す。


[ ]
RE:01566 配列のソートNo.01567
山紫水明 さん 00/10/29 16:06
 
    encodingshiftjisさん こんにちは。

》研究され尽くされた分野なので、変なのを出すのはちょっと気おくれ
 そうなんででしょうね,私はその方面に暗い文科系人間なもので。
 あっ,文科系の方がすべて暗いというのではありません,念のため。(^^;

》▲大小比較は何を使うか?
 単純に文字符号順でいいです。

》▲処理の形態
》全面新規ソート 対 ソート済み配列に要素の追加か――全面新規
》重複キーは多いか少ないか――基本的になしということで

》ソース順の保存は必要か?(同一キーの時)アルゴリズムによっては
》原始配列を保存しないソートになる。――保存の必要なし

》ソート前後のサービス処理も考えるか?――マクロの一部に使います
》ソート対象にしない物が混在するか――なし
》重複キーは単一化するか――しない

》▲実現の形
》秀丸マクロで作る――こちらで

》すぐ出来るのは
》新面を開いて、配列を書き出し、SORTコマンド実行の結果を
》結果を配列に戻す。
 これはやってみました。もう少しスマートにできないかと。

 以上のことでいかがでしょう。

 では, (^^)/~
                                        山紫水明


[ ]
RE:01567 配列のソートNo.01568
ENCODINGSHIFTJIS さん 00/10/30 11:33
 
テストは以下でしかやっていません、パラメータも最適化してませんが。

//マクロ内の文字列の細かい扱いが分からないが
//文字列代入は値をコピーするか? 不要になった文字列は
//いつ回収するのか(多数繰り返したり、巨大データを処理する時は効く
//回収が遅れると、マクロ実行中に急に遅くなったりする)
//瞬間ソートを求めるなら 最適化C++コンパイラとか,ASMで書かなきゃ
//ソートは問題分野ごとに最適化するものだ、暗号解読、データ圧縮、
//塩基配列解析、並列計算機、ハードウェアソーター、DB、...
//
//秀丸の比較も「文字符号順」じゃない , LOCAL を見ている ?
//ユルユルで作ると D.SHELLソート風でやってみました
//同一キーの時の原始配列は保存しない
// D.SHELL sort (String)
// dshell.mac
$phrase[0]="本能";
$phrase[1]="幸福論";
$phrase[2]="勝訴ストリップ";
$phrase[3]="積木遊び";
$phrase[4]="性的ヒーリング";
$phrase[5]="無罪モラトリアム";
$phrase[6]="罪と罰";
$phrase[7]="ギブス";
$phrase[8]="ここでキスして。";
$phrase[9]="歌舞伎町の女王";
$phrase[10]="依存症";
$phrase[11]="眩暈";
$phrase[12]="Σ";
$phrase[13]="虚言症";
$phrase[14]="丸の内サディスティック";
$phrase[15]="シドと白昼夢";
$phrase[16]="モルヒネ";
$phrase[17]="正しい街";
$phrase[18]="17";
$phrase[19]="君ノ瞳ニ恋シテル";
  #tlen=20;  // table size
// ここから
#x=#tlen; while(#x>0){#x=#x-1;#p[#x]=#x;} // #p 初期化
#span=#tlen;

while(#span>3){ #span=#span-#span/4; #x=#tlen;
while(#x-#span>0){#x=#x-1;
if($phrase[#p[#x]] < $phrase[#p[#x-#span]]){
     #swap=#p[#x];    #p[#x]=#p[#x-#span]; #p[#x-#span]=#swap; }
 } }
             #flag=true;
while(#flag){#flag=false; #x=#tlen;
while(#x-1>0){#x=#x-1;
if($phrase[#p[#x]] < $phrase[#p[#x-1    ]]){#flag=true;
     #swap=#p[#x];    #p[#x]=#p[#x-1    ]; #p[#x-1    ]=#swap; }
 } }
// ソート完了 $phrase[#p[0...#tlen]] で取り出す
// インデクスの回し方で 昇順・降順が切替えできる

gofileend;insertreturn;
      #x=#tlen;
while(#x>0){#x=#x-1; insert $phrase[#p[#x]]; insertreturn; }
insert "----------------------"; insertreturn;
      #x=0;
while(#x<#tlen){insert $phrase[#p[#x]]; insertreturn; #x=#x+1;}


 眩暈
 無罪モラトリアム
 本能
 積木遊び
 正しい街
 性的ヒーリング
 勝訴ストリップ
 罪と罰
 幸福論
 君ノ瞳ニ恋シテル
 虚言症
 丸の内サディスティック
 歌舞伎町の女王
 依存症
 モルヒネ
 シドと白昼夢
 ここでキスして。
 ギブス
 Σ
 17
 ----------------------
 17
 Σ
 ギブス
 ここでキスして。
 シドと白昼夢
 モルヒネ
 依存症
 歌舞伎町の女王
 丸の内サディスティック
 虚言症
 君ノ瞳ニ恋シテル
 幸福論
 罪と罰
 勝訴ストリップ
 性的ヒーリング
 正しい街
 積木遊び
 本能
 無罪モラトリアム
 眩暈
 

[ ]
RE:01568 配列のソートNo.01569
山紫水明 さん 00/10/31 12:44
 
ENCODINGSHIFT さん,こんにちは。

 ご教示ありがとうございました。このアルゴリズムはいろいろ応用できそうです。
#span=#span-#span/4 の部分,実をいうとまだよく理解できませんが,これでいけ
るのですね。

 目下,メインのパソコンが CRASH してしまい,その修復にちょっと手間取って
いますので,十分な検証ができませんが,とりあえず。

  山紫水明

[ ]
RE:01565 配列のソートNo.01570
かかし さん 00/10/31 13:08
 
かかしです、こんにちは。

> $data[#n] の配列があります。(#n はさしあたり 100 程度)
> これをソートするマクロを作りたいのですが,方法ご存じの方教えてください。
> 一つ一つ比較して力ずくでやっていけばできるのですが,何かもっと効率的な方
>法があると以前に何かで見たような気がしますが,手許に見つかりませんので。

配列のソート・・ではないのですが、マクロでソートを実現する
方法として以前こちらの会議室で

阿久津さんに

////////////////////////////////////////////////////////////
// Hqsort.mac ver 1.00
    :
//何でクイックソートと合成したアルゴリズムが直接選択法なのだ?
//それは、効率の悪いソートのアルゴリズムの中で、
//直接選択法が最も交換回数が少ないからです。
////////////////////////////////////////////////////////////

というマクロを勧めて頂きました。

参考までに見ていただいたらどうでしょう?

---かかし

[ ]
RE:01570 配列のソートNo.01571
山紫水明 さん 00/10/31 16:40
 
    かかしさん こん○○は。

 レスありがとうございます。
 阿久津さんの Hqsort.mac は私も知っています。
 ちゃんと解析すれば,配列のソートにも書き直せるかもしれないと思いましたが,
つい面倒だったもので(^^),ここで尋ねたわけです。

 では, (^^)/~
                                        山紫水明


[ ]
RE:01565 配列のソートNo.01572
安久津 さん 00/10/31 17:50
 
●山紫水明さんへ。

  ##size = 50;
  ##i = 0; ##ch = 'Z';
  while( ##i < ##size ){
    $data[##i] = char(##ch) + str(tickcount % 11);
    insert $data[##i] + ",";
    ##ch = ##ch - 1; if( ##ch < 'A' ) ##ch = 'Z';
    ##i = ##i + 1;
  }
  insert "\n-----\n";
  call sSort ##size;
//  call bSort 0, ##size - 1;
  ##i = 0;
  while( ##i < ##size ){
    insert $data[##i] + ",";
    ##i = ##i + 1;
  }
  beep;
endmacro;
// ---------------------------------------------------------------
// 「C言語によるはじめてのアルゴリズム入門」河西朝雄 技術評論社
// シェルソートからそのまま移植。
sSort:
  ##size = ##1;
  ##i = ##size / 3; ##gap = 1;
  while( ##gap < ##i ) ##gap = (3 * ##gap) + 1;

  while( ##gap > 0 ){
    ##i = ##gap;
    while( ##i < ##size ){
      ##j = ##i - ##gap;
      while( ##j >= 0 ){
        if( $data[##j] > $data[##j+##gap] ){
//if( dllfunc("STRICMP",$data[##j], $data[##j+##gap]) > 0 ){
          $$tmp = $data[##j]; $data[##j] = $data[##j+##gap];
          $data[##j+##gap] = $$tmp;
        }else{
          break;
        }
        ##j = ##j - ##gap;
      }
      ##i = ##i + 1;
    }
    ##gap = ##gap / 3;
  }
return;
// ---------------------------------------------------------------
// Hqsort.mac の基本部分から。
// ただし、call ネストの上限チェック無し。
bSort:
  ##low = ##1; ##high = ##2;
  $$mid = $data[ (##low + ##high) / 2 ];
  while( ##low <= ##high ){
    while( $data[##low] < $$mid ) ##low = ##low + 1;
    while( $data[##high] > $$mid ) ##high = ##high - 1;
// while( dllfunc("STRICMP",$data[##low], $$mid) < 0 ) ##low = ##low + 1;
// while( dllfunc("STRICMP",$data[##high], $$mid) > 0 ) ##high = ##high - 1;
    if( ##low <= ##high ){
      $$tmp = $data[##low];
      $data[##low] = $data[##high];
      $data[##high] = $$tmp;
      ##low = ##low + 1; ##high = ##high - 1;
    }
  }
  if( ##1 < ##high ) call bSort ##1, ##high;
  if( ##low < ##2 ) call bSort ##low, ##2;
return;
// おしまい。

100程度なら、sSort のほうが bSort より速いし、安全です。
ではでは。


[ ]
RE:01570 配列のソートNo.01573
安久津 さん 00/10/31 17:50
 
●かかしさんへ。
電八のメールはゼロパディングしているので、文字列としての比較でも
問題なかったのでした。(^^;)
# Hqsort.mac は公開やめました。

// 行選択して実行。選択範囲をソートする。
  if( ! selecting ){ beep; endmacro; }
  if( (seltopx + selendx) != 0 ){ beep; endmacro; }
  disableinvert;
  cut;
  call pasteSort;
beep;
endmacro;
////////////////////////////////////////////////////////////
// AKUTSU Toshiyuki #いつ書いたか忘れた。(^^;)
// クリップボードの文字列をソートして、
// カーソル位置の論理行頭に貼り付けるサブルーチン。
//
// M.Tsukamoto 氏 Sort.mac 99/05/10 から、クリックボードを
// 待ち行列扱いする用途を利用。バブルソートを2分挿入法に変えた。
pasteSort:
  ##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; // selectlineより速い。
      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 = tickcount + 1000; }
    $$cmp = getclipboard;
  }
  movetolineno 1, ##first; delete;
return;
////////////////////////////////////////////////////////////
// 欠点。
// もし被ソートデータに 0x0a 以下の制御コードが存在する場合
// 正しいソートができないことがある。
// 具体例。
// AA
// AA\t
// すなわち、AA をクリップボードから取得すると $$cmp == "AA\x0a"
// 比較対象が、"AA\x09" となるので、
// "AA\x0a" > "AA\x09" を満たしてしまう。
// 本来は、"AA" < "AA\x09" となるべき。
//
// 選択方法を selectline にしても解決しない。 \x0d が問題。
// 完全には
// $$temp = getclipboard;
// $$cmp = leftstr($$temp,strlen($$temp)-1);
// である。# chop, chomp ちょうだい。(^^;)
////////////////////////////////////////////////////////////

サブルーチンだけを切り取り、return を endmacro に変えて、
macrodir + "\\pastesort.mac" で保存すれば、
他のマクロから、簡単に利用できます。
disableinvert; selectall; cut;
execmacro "pastesort.mac";

ではでは。

[ ]
RE:01573 配列のソートNo.01574
かかし さん 00/10/31 18:43
 
かかしです、こんにちは。

阿久津さん、こんにちは。

#すべて余談です。

>●かかしさんへ。
>電八のメールはゼロパディングしているので、文字列としての比較でも
>問題なかったのでした。(^^;)

うーん、懐かしい、あのころは電八にこだわっていたからなあ・・
よく覚えてましたね。びっくり。

もう、メーラも乗り換えて1年くらい経ちます・・。
鶴亀メールにまた乗り換えるかも・・。

># Hqsort.mac は公開やめました。

そうそう、Hqsort.macは、電八以外のところで活躍しています。
クリックして、範囲選択したところでソートできるなんてちょっとしたとき
便利です。

でも、公開やめてしまったんですね(^^;

---かかし

[ ]
RE:01574 配列のソート - 余談パートツーNo.01575
番頭++ さん 00/10/31 19:05
 
> 阿久津さん、こんにちは。
> #すべて余談です。

阿久津さん、こんばんは。余談パートツーです。
なんで sort になると、阿久津さんは、意地になるのでしょう。冗談です。

配列変数でソートしても参照も遅いでしょう。特に、件数が多いときには、別の
「秀丸」の窓にして、検索のほうが速いでしょう。という個人的な意見です。

[ ]
RE:01575 配列のソート - 余談パートツーNo.01576
安久津 さん 00/10/31 21:23
 
こんにちは番頭++さん。

>阿久津さん、こんばんは。余談パートツーです。
>なんで sort になると、阿久津さんは、意地になるのでしょう。冗談です。
意地になる理由がありました。(^^;)

ご存知の通り、秀丸には「現在入力中の文字列から、指定した辞書ファイルを参照し
て、
入力候補を列挙する入力補完」の機能がありません。Javaは C などの省略表記をさける
ために各識別子が非常に長いです。入力するのは面倒です。おぼえたての言語の識別
子の
入力も面倒です。最近の話ですが、Access VBA を使った後に、VBScript を使いまし
たが、
エラー頻発でした。それは、Access VBA で使える組み込み関数が VBScript では存在し
ないからです。これらはすべて入力補完機能があれば済む話です。

というわけで、ソートは「入力補完」を実現するための道具のひとつとしてずっと考
えて
いました。#んでも「前方一致検索」のほうが苦労したような。

●ソートの問題
他のプログラムでソートしたデータを、秀丸の文字列比較演算で、
管理するとヤバイです。
例えば、sort.exe は、"_" > "a" です。秀丸は、"_" < "a" です。
 "_" は、通常名前構成文字なのでヒドイ目にあいます。
sort.exe => "pre_hoge" > "prefix_hoge"
Hidemaru => "pre_hoge" < "prefix_hoge"

もし、秀丸の文字列比較演算をつかってデータを参照するのなら、
ソートは秀丸マクロで行うか、同じソート結果になるプログラムを自力で
作成しなければなりません。

●前方一致検索の問題
大文字小文字を無視して、前方一致検索をするには、田楽 DLL の
 dllfunc("STRICMP",$str1, $str2) を使うことになります。
ということは、ソートにも影響があります。
 dllfunc("STRICMP",$str1,$str2) と同じ結果になるソートを行わなければ
なりません。安全なのは、ソートマクロでの比較に田楽 DLLを使うことです。
# sSort は、STRICMP の動作テストに使ってたものなので、
# 田楽 DLL の記述が混入しています。

●ということで
秀丸でのソートをえんえん考えてきた次第です。
比較が文字コードでどうだとかも、ぜんぶ「入力補完」のためです。

●現在
VBScript(走上 WSH) の StrComp(str1, str2, 1) は、
田楽DLLの dllfunc("STRICMP",$str1, $str2) と似ています。(同じではない)
少なくとも、[0-9A-Za-z_] の名前構成文字については同じです。
VBS は StrComp() が用途に合い、正規表現も使えて、且つレジストリーも簡単に
扱えるので、全ての目的に適合しました。
大変な処理を VBS にやらせて、秀丸マクロ + 田楽DLL で恩恵を
享受します。しあわせになりました。(^^)

#各プログラミング言語用辞書ファイルの切り替えが必要だったので、
#結局自力でレジストリを管理することにしました。m(__)m>杉浦さん

ではでは。
# JPerl も考えたんですけど、strCmp を実装するのが面倒で。
# バイナリー生成する言語でも比較関数の実装が面倒になるか結局。
  sub strCmp( $ $ ){
    my ($a, $b) = @_;
    $a = lc( $a );
    $b = lc( $b ); # 一個一個文字を調べるなんてヤダ。
    return $a cmp $b;
  }
  @file = glob('*');
  @file = sort strCmp @file;
  print join("\n", @file) . "\n";
  <>;

[ ]
RE:01576 配列のソート - 余談パートツーNo.01577
杉浦 まさき さん 00/11/01 00:01
 
安久津さん、こんばんは。
杉浦 まさき です。

>VBScript(走上 WSH) の StrComp(str1, str2, 1) は、
>田楽DLLの dllfunc("STRICMP",$str1, $str2) と似ています。(同じではない)
>少なくとも、[0-9A-Za-z_] の名前構成文字については同じです。

ハイフン(-)とアポストロフィ(')の位置の違いであれば、
思い当たる節はあります。

で、指摘されるまでは、田楽鯖&DLLの stricmp
(というか Win32API の lstrcmpi)は
単純な文字コードによる比較だと思ってました(^^;。
というわけで、僕の意図とは異なってるわけですが、
今更変えるのも何なんでそのままにしておきます(^^;。


[ ]
RE:01569 配列のソートNo.01578
ENCODINGSHIFTJIS さん 00/11/01 08:49
 
>#span=#span-#span/4 の部分,実をいうとまだよく理解できませんが,これでいけ

新比較間隔 := 0.75 * 前比較間隔;
ということです。総比較回数の最少になる係数はもう少し小さい。

しかし、係数の微調整より、秀丸マクロの要素演算の[計算コスト]が
わかるような説明が無いので、作る方向がつかめない。
文字列代入のコストは高いかもしれない、と[仮定]して #p で間接参照
にしたが、そうでなければ #p 無しの 直接交換でかまわない。
配列のアクセスも Fortran コンパイラのように早いのか?
それとも、単なる 便利な書き方なのか。


[ ]
RE:01572 配列のソートNo.01579
山紫水明 さん 00/11/01 16:10
 
    安久津さん こんにちは。

 どうもわざわざご教示ありがとうございました。
 なお,前回の引用ではご尊名の字を間違えて失礼いたしました。<m(--)m>

》// 「C言語によるはじめてのアルゴリズム入門」河西朝雄 技術評論社
》// シェルソートからそのまま移植。

 どうもソートの問題はC言語の初歩の問題だったようですね。
 Cは以前にやりかけましたが,時間がとれなくて止めてしまいました。

 では, (^^)/~
                                        山紫水明


[ ]
RE:01577 配列のソート - 余談パートツーNo.01580
安久津 さん 00/11/01 17:29
 
こんにちは杉浦さん。

>ハイフン(-)とアポストロフィ(')の位置の違いであれば、
>思い当たる節はあります。
記号については考えていませんでした。
MS-Office の VBA で名前構成文字になりえる、全角文字などを考えていました。
rst社員マスタ, cmdメール送信_Click

このような2バイト文字の場合はユーザー定義のものなので、
調べてはいません。VB の識別子は英字の大文字小文字を区別しないことは有名
ですが、VBA では半角全角までも無視して通用する場合があります。

田楽DLL の STRICMP では、
"A" == "a" && "A" == "a" && "A" < "A"

VBS の StrComp(,,1) では、
"A" == "a" == "A" == "a"

ただし、半角全角文字混在の名前は、秀丸の方がひとつの「名前」として扱いま
せん。「名前」というより「単語」といったほうがピンとくると思いますが。
wordleft, selectword などの動作のことです。

ではでは。

[ ]
RE:01578 配列のソートNo.01581
安久津 さん 00/11/01 17:29
 
こんにちは encordingsjis さん。

>しかし、係数の微調整より、秀丸マクロの要素演算の[計算コスト]が
>わかるような説明が無いので、作る方向がつかめない。
私の場合(sSort)、本に書いてあった数列をそのまま使っただけでなにも
考えていませんでした。

>文字列代入のコストは高いかもしれない、と[仮定]して #p で間接参照
>にしたが、そうでなければ #p 無しの 直接交換でかまわない。
Java 方面で、String より StringBuffer を使うというだけです。
VBS や JPerl では直接交換しかおこないません。
# 深いコピーはきついデータを除く。その基準はなんだろう?>自分
VBS String(Variant)のアペンドの繰り返しは異常に遅くなるのは知ってい
ますが。以前ビックリした。
str1 = str1 & "hoge"
#[仮定]はいつもの言語に依存するのかな?

>配列のアクセスも Fortran コンパイラのように早いのか?
>それとも、単なる 便利な書き方なのか。
後者です。sSort では、なんも考えていないんです。(^^;)
# pasteSort は秀丸の弱点が排除できていますが。

ではでは。...((((( ((;^^)ニゲチャオー || ROM の世界 ||

[ ]
RE:01581 配列のソートNo.01582
ENCODINGSHIFTJIS さん 00/11/02 11:17
 
># pasteSort は秀丸の弱点が排除できていますが。
たしかに、挿入の扱いが簡単にできているし。クリップボードと面で
2ウェイ マージソートも 作れるでしょう。行数は2倍以上になりそうなので
やめますが。
配列アクセスの速さを、測ってみました。 不思議な結果で
要素数に比例して均等に遅くなる。 log(N) でもないし 先頭が早い
でもない。 Sort自体が N log(N) だから 合わせて N**2 log(N)
マクロのデータ領域が 10倍に なっても それを生かす アーキテクチャの
進歩がないとー

// ary access speed test
// arytest.mac
//
#s=16;// 16,32,64,128 としてみる
#x=-1;while(#x<#s){#x=#x+1;$s[#x]="99999999999999999999";}

#t1=tickcount;
#x=999;while(#x>0){#x=#x-1; $d=$s[0];}
#t2=tickcount;
#x=999;while(#x>0){#x=#x-1; if($s[#s/4]>"0")continue;}
#t3=tickcount;
#x=999;while(#x>0){#x=#x-1; $d=$s[#s/2];}
#t4=tickcount;
#x=999;while(#x>0){#x=#x-1; $d=$s[#s];}
#t5=tickcount;
// ヒステリシスはあるか
#x=999;while(#x>0){#x=#x-1; $d=$s[0];$d=$s[1];$d=$s[2];$d=$s[3];$d=$s[4];$d=
$s[5];$d=$s[6];$d=$s[7];}
#t6=tickcount;
#x=999;while(#x>0){#x=#x-1; $d=$s[7];$d=$s[6];$d=$s[5];$d=$s[4];$d=$s[3];$d=
$s[2];$d=$s[1];$d=$s[0];}
#t7=tickcount;

menu str(#t2-#t1),str(#t3-#t2),str(#t4-#t3),str(#t5-#t4),str(#t6-#t5),str(#t
7-#t6);

__END__

[ ]
RE:01582 配列のソートNo.01583
安久津 さん 00/11/02 22:44
 
シャシャリデルー (^^;)) )))))...|| ROM の世界 ||

●arytest.mac について
>配列アクセスの速さを、測ってみました。 不思議な結果で
>要素数に比例して均等に遅くなる。 log(N) でもないし 先頭が早い
要素数に比例している部分もあります。

>   #s=16;// 16,32,64,128 としてみる
>   #x=-1;while(#x<#s){#x=#x+1;$s[#x]="99999999999999999999";}
配列操作ではなく、文字列のサイズに注目しました。
この $s[#x] に代入している文字列を、もっと大きなサイズにしてみます。
//環境は P-166MMX, 32MB

$result = str(#t2-#t1)+","+str(#t3-#t2)+","+str(#t4-#t3)+","+
          str(#t5-#t4)+","+str(#t6-#t5)+","+str(#t7-#t6);

#s = 16; // $s[#x]=20 バイト
1112,1456,1304,1291,5741,5809

#s = 16; // $s[#x]=40 バイト
1373,1800,1593,1579,6867,6935

#s = 16; // $s[#x]=80 バイト
1881,2458,2170,2156,9133,9201

要素数に比例して遅くなる(純粋な配列操作の)側面と、変数に代入している文字列
の総量に比例して遅くなる側面があるように見えます。#s が一定なので明白。

純粋に文字列の大きさがマクロにどのような影響をあたえるか調べたくなります。

●なんでやねん.mac
     // $s に代入する文字列を 500, 1000, 2000 バイトとかにします。
    $s = "大きなサイズの文字列";
    ##i = 0;
    ##t1 = tickcount;
    while( ##i < 1000 ){
        // $d = rightstr($s,1); // <- これは関係させずに、
        ##i = ##i + 1;          // たんにループさせるだけ。
    }
    ##t2 = tickcount;
    insert str(##t2 - ##t1) + "\n";
    beep;
endmacro;

「なんでやねん.mac」の結果は以下の通りです。

 500バイト => 303
1000バイト => 494
2000バイト => 948

ではでは。...((((( ((;^^)テッシュウ || ROM の世界 ||

[ ]
RE:01583 配列のソートNo.01584
encodingshiftjis さん 00/11/04 01:25
 

// 2次元配列と1次元配列の速さは?
// arydim.mac

#x=1024;while(#x>0){#x=#x-1;$s[#x]="999";}
menu "ggg";
#x=32;while(#x>0){#x=#x-1;
#y=32;while(#y>0){#y=#y-1;$e[#x][#y]="999";}
 }
menu "ddd";
#t1=tickcount;
#x=999;while(#x>0){#x=#x-1;$d=$s[0];}
#t2=tickcount;
#x=999;while(#x>0){#x=#x-1;$d=$e[0][0];}
#t3=tickcount;
//
gofileend;insert "//"+str(#t2-#t1)+",#"+str(#t3-#t2)+"\n";

//48350,#57035   文字列 25バイト  要素数に比例する遅さは変わらず
//39445,#46425            3バイト  気にするほどの速度差はない
------------------------------------------------------------
// 配列ではなく 変数の総数は影響するか?
// valcount.mac
//
$s000="9";
$s001="9";
$s002="9";
$s003="9";
$s004="9";
$s005="9";
$s006="9";
$s007="9";
$s008="9";
$s009="9";

#t1=tickcount;
#x=999;while(#x>0){#x=#x-1;$d=$s009;}
#t2=tickcount;

gofileend;insert "//"+str(#t2-#t1)+"\n";

//125  $s 10個
//215     20
//390     40        配列要素数ばかりでなく、文字列変数もカウントに入ってい
て 遅くなる。エー!文字列変数の総数は鬼門だ、というより
改善項目にしないと、普通のプログラム言語とは張り合えない。
秀丸マクロの暗部だ
現在の警告としては、配列要素も含めて文字列変数を200個以上
使って多数回アクセスする濃い処理をする時は覚悟すること。

秀丸の文字列変数は部分変更できなくとも、値コピー代入なのか。
では、#p で間接参照は まあまあ かな。平均文字列長によるが。

rightstr を leftstr に変えても同じ時間がかかるし、配列と
同様に文字列長に比例して遅くなる。不思議?まるで 一度作業領域に
全部コピーしてから。値を生成してるみたいだ?。
では、配列アクセスも何かのマップを毎回どこかの作業域にコピー
しているのか。

しかし、秀丸3.06 の改版履歴 の
   ・マクロの変数領域の最大を64KBから640KBに
が 今の配列アクセスのオーダ O(N) で生かされない懸念がある。
単純に10倍のデータを10倍の時間では処理できないから。
静的配列の O(1) に、と言わなくとも O(N) では、アルゴリズム集
などをそのまま コピーしてマクロを作れないな。


[ ]