新規投稿は記事一覧のフォームからお願いします
> これは,例えば 1020 とか 1040 とかのときは遅くならないのですか?
> #55 " " &?("%d",o) #m
> ……これを少しだけまとめて……
> #55 &?(" %d",o) #m
> なぜか1030から始まる変換だけ遅い。
> 重複した番号が発生したときに著しく遅くなる、とかありそう。
> 相変わらずツリーが乱れているようですが、大丈夫でしょうか。ツリーが乱れたまま過去ログにプッシュアウトされたりすると、ひどいことに なりそうな気もします。回線に不具合がありそうなら、携帯電話経由なり、 何らかの方法で解決されたほうがよろしいかと。 さて、要素技術のツリーが深くなってしまったので、浅めのところにつけます。 とりあえず、当社比でかなりの高速化が達成できたのでアップします。 とはいえ、いろいろと聞き倒した要素技術のうち、実際に使ったのは検索の 戻り値だけ、というような感じです。 = renum.def(ver. 0.20) i:初期値 initial num a:増分 addition n:新行番号 new num o:旧行番号 old num c:旧番検索結果 check count h:処理中の行 handling line ※論理行番号 ln N88-BASICのコードは半角大文字が前提(半角小文字はあえて未対応) *m 1 ^^ "renum.def" ;初期設定 ;vwxの常駐確認とか? a=10, n=o=0, mp[=2, ps[=pa, RX[+, Dn[-, &s &01 #^ #< ;カーソルを先頭行の行頭にして &n i=r, ;初期値取得 (r+1)??{ &m(41) >e } ;準備ができていないなら終了 ;メインループ ;先頭行は行番号の変更なし :w ;while(次の行に動ければ) #> #d ;次の行にカーソルを移動し #d (r==-1)?>u ;その結果が最終行ならループ脱出 #< h=ln, c=0, ;検索結果初期化 &n o=r, ;旧行番号取得 n=i+(h-1)*a, ;新行番号算出 #55 " " &?("%d",o) #m #r c+=r, #c c+=r, ;旧番存在確認 &#J(h) #< #t &?("%d",n) ;処理している行に戻って新番化 (c==-2)??{&10} ;旧番号存在時のみ置換実施 >w :u ;後処理 #56 "\([ \t]+\)FTHEN" #m "\1THEN" #m "ay" #56 "\([ \t]+\)FELSE" #m "\1ELSE" #m "ay" #56 "\([: \t]+\)FGOTO" #m "\1GOTO" #m "ay" #56 "\([: \t]+\)FGOSUB" #m "\1GOSUB" #m "ay" #56 "\([: \t]+\)FRESTORE" #m "\1RESTORE" #m "ay" #56 "\([: \t]+\)FRESUME" #m "\1RESUME" #m "ay" Dn], RX], ps], mp], :e ;end &d . 01: ;最初のチェック ;例えば、全ての論理行が行番号+半角空白で始まっていることの確認、とか。 . 10: #56 "\([ \t]+\)THEN\([ \t]+\)" &?("%d",o) "$$" #m "\1FTHEN\2" &?("%d",n) #m "ay" #56 "\([ \t]+\)THEN\([ \t]+\)" &?("%d",o) "\([^0-9]\)" #m "\1FTHEN\2" &?("%d",n) "\3" #m "ay" #56 "\([ \t]+\)ELSE\([ \t]+\)" &?("%d",o) "$$" #m "\1FELSE\2" &?("%d",n) #m "ay" #56 "\([ \t]+\)ELSE\([ \t]+\)" &?("%d",o) "\([^0-9]\)" #m "\1FELSE\2" &?("%d",n) "\3" #m "ay" #56 "\([: \t]+\)GOTO\([ \t]+\)" &?("%d",o) "$$" #m "\1FGOTO\2" &?("%d",n) #m "ay" #56 "\([: \t]+\)GOTO\([ \t]+\)" &?("%d",o) "\([^0-9]\)" #m "\1FGOTO\2" &?("%d",n) "\3" #m "ay" #56 "\([: \t]+\)GOSUB\([ \t]+\)" &?("%d",o) "$$" #m "\1FGOSUB\2" &?("%d",n) #m "ay" #56 "\([: \t]+\)GOSUB\([ \t]+\)" &?("%d",o) "\([^0-9]\)" #m "\1FGOSUB\2" &?("%d",n) "\3" #m "ay" #56 "\([: \t]+\)RESTORE\([ \t]+\)" &?("%d",o) "$$" #m "\1FRESTORE\2" &?("%d",n) #m "ay" #56 "\([: \t]+\)RESTORE\([ \t]+\)" &?("%d",o) "\([^0-9]\)" #m "\1FRESTORE\2" &?("%d",n) "\3" #m "ay" #56 "\([: \t]+\)RESUME\([ \t]+\)" &?("%d",o) "$$" #m "\1FRESUME\2" &?("%d",n) #m "ay" #56 "\([ \t]+\)RESUME\([ \t]+\)" &?("%d",o) "\([^0-9]\)" #m "\1FRESUME\2" &?("%d",n) "\3" #m "ay" * 旧バージョンは、とにかく全ての行を変換する、というものでした。 ある意味、わかりやすいロジック。だけど、それが遅くなる根本原因。 なので、必要なところだけ変換するようにしました。 そして、必要なところはどこか、というのを確認するのに検索を使いました。 また、今回は論理行番号を使うコードということもあって、検索後の戻りに ついても論理行番号を使ってみました。 さて、実際にどのくらい高速化したか測定してみました。 測定に使った行番号変換に使ったBASICプログラムは、自作のオセロのコード。 論理行数約220行。 あいにく、ストップウォッチは手元にありません。会社で使っているスマホなら ストップウォッチがついているのですが、手元のガラケーにはストップウォッチ の機能がないので、デジタルの時計表示を目で追いかける形。なので、精度に ついては気にしてはいけない。 まず、めざらさんのマクロ。15秒から16秒で完了です。 次、私の旧バージョン。&sを使わないと、概ね3分くらいかかります。 &sを使ったときの速度は測っていませんが、半分にはならない。 そして、私の今回のバージョン。 &sを使わないと30秒前後。 そして、&sを使うと、やった、10秒強。 ただ、測定して不思議に思ったこと。 元のBASICは、行番号1000から始まるコードです。 これを、10000から始まるコードに変換することをクリアするのが最初。 これができなければロジックにバグがある。 つぎに、変なバグが紛れ込んでいたらわかるように、990から始まる変換と、 1030から始まる変換を行ってみました。 変換結果はいずれも、めざらさんのマクロと一致したので、あまりにも致命的な バグはないと思うというか、全く異なるロジックであるにもかかわらず同じ誤り を犯すというのは考えにくいので、この辺は大丈夫でしょう。 ただ、所要時間の面では面白い結果となりました。 私の作ったマクロでは、なぜか1030から始まる変換だけ遅い。 旧バージョンは、他の変換が3分前後なのに対して20秒くらい遅いだけなので、 比率ではたいした事はない。 ところが新バージョン。 画面表示を止めないものは、他が25秒くらいに対して38秒。 画面表示を止めたものは、他が10秒くらいに対して17秒。 ん〜、変換前後の桁数の問題ではないな。 なんか、重複した番号が発生したときに著しく遅くなる、とかありそう。 この辺を解決できて常に一定の速度が出せるアルゴリズムを思いつければ面白い のだけど、なかなか難しそう。 また、想定外の何か特殊な場合に変換を誤ることもありそう。 これはそういうものにお目にかからないと実際に解決するのは無理そうだけど。
> すり替えしか方法がないのでしょうか。
> 簡単に、プッシュポップで退避させて、ということができるとうれしい
> 簡単に書き換わってしまうので,注意が必要
> 4バイトのバッファを用意してすり替えるのが吉かと。
> > #rとか#cの場合、検索して発見できた、または発見できなかったという結果は
> r に返ってきます。
> ■内部レジスタ
> (式)で評価した値が内部レジスタに格納される。
> #rとか#cの場合、検索して発見できた、または発見できなかったという結果は
> 戻り値(r)と内部レジスタを混同しないようにしましょう。
> あくまでも全置換の直後の r に置換した数が格納されるということしか分かりません。
> 知りたかったのは、8000h 以上の値を返してくることはあるのか、ということ
> 知ってて敢えて質問していません? いけずやなぁ……
> 置換数の最大値って、符号付きで返ってくるのですか?
> v1.6 のマニュアル類には記載が見つからないようですね。
> > プッシュの行がコメントになっていると、異常動作の確率が圧倒的に高い。
> プッシュをせずにポップだけ行っていたら,動作が異常になるのは必然です。