HSPポータル
サイトマップ お問い合わせ


HSPTV!掲示板


未解決 解決 停止 削除要請

2009
0424
p、USAGI大型ノート形式をもっと高速に7解決


p、USAGI

リンク

2009/4/24(Fri) 09:57:33|NO.24776

大きなデータ(ノート形式)の後方の場所の処理(notegetなど)ほど処理時間がかかってしまいます。
もっと高速にできないでしょうか?
10万行(約4MB)にもなると2時間以上かかります。

以下のスクリプトではnoteget命令だけですが実際にはもっと・・・
ちなみに私のPCでは1回目34ms、10回目682msかかります。

#include "winmm.as"
timeBeginPeriod 1 mes "少しお待ちください。" aaa="acb\n" repeat 10000 bbb=""+bbb+""+aaa loop notesel bbb ccc=0 mes "start" repeat 10 wait 50 timeGetTime : st=stat repeat 1000 //1000回繰り返し処理の経過時間取得 noteget ddd,cnt+ccc //この処理時間を計る loop timeGetTime : et=stat mes ""+(cnt+1)+"回目の処理で"+(et-st)+"ミリ秒経過しました。" ccc+=1000 loop timeEndPeriod 1 stop



この記事に返信する


SYAM

リンク

2009/4/24(Fri) 11:01:41|NO.24777

note命令はいつ誰が書き換えるとも知れないバッファを扱うため、実行するたびにバッファを検索しなおすしかないので時間かかるんでしょうね。

バッファを分割して扱ってはどうでしょう?
分割した各データの行数がわかれば 目的の行がどの分割データの何行目にあるか を計算することは可能ですから、より小さなバッファに対して noteget を実行できます。
notemaxが重いままになるかもしれませんが、もし可能なら行数を自前で管理することでそこも高速になるんじゃ ないかなー。。



レノス

リンク

2009/4/24(Fri) 17:22:11|NO.24779

一番初めに getstr とかで全部行ごとに区切って配列変数に放り込んでしまえば、( これが遅いでのすが )
文字列を得るときの速度はほとんど気になりません。


#include "winmm.as" mes "少しお待ちください。" sdim buf, 50001 repeat 10000 buf += "abc\n" loop timeBeginPeriod 1 // 文字列を分割 timeGetTime : st = stat index = 0 sdim sLine sdim sLineArray, 100 repeat getstr sLineArray(cnt), buf, index : index += strsize if ( strsize == 0 ) { break } loop timeGetTime : et = stat mes "分割処理に "+ ( et - st ) +"ms 掛かりました。" // いろいろ繰り返す repeat 10 await 1 timeGetTime : st = stat repeat 1000 // 1000回繰り返し処理の経過時間取得 stmp = sLineArray(cnt + x) // この処理時間を計る ; noteget stmp, cnt + x loop timeGetTime : et = stat mes "["+ cnt +"] の処理で"+ (et - st) +"ミリ秒経過しました。" x += 1000 loop sdim buf // 元の文字列を破壊 // 複数行文字列に直す( 保存するときとか ) timeGetTime : st = stat foreach sLineArray buf += sLineArray(cnt) +"\n" // シンプルだが遅いやり方 loop timeGetTime : et = stat mes "複数行文字列化に "+ (et - st) +"ms 掛かりました。" timeEndPeriod 1 stop

自分のPCでは、
分割:1400ms
#0~9:3ms
最後:600ms
程度でした。



Kpan

リンク

2009/4/24(Fri) 20:43:09|NO.24785




p、USAGI

リンク

2009/4/25(Sat) 01:22:08|NO.24793

とりあえずタイプAと、タイプBに振り分けるのが目的なので、
0行目だけで処理すれば処理時間がある程度安定しますので
これを使おうかと思います。(自己解決?)

レノスさんのスクリプト、参考になりました。
どこかで使えればと思います。

みなさん、ありがとうございました。
もっといい方法があればレス下さい。

#include "winmm.as"
timeBeginPeriod 1 mes "少しお待ちください。" aaa="abc\nxyz\n" repeat 5000 bbb=""+bbb+""+aaa loop eee="" : fff="" notesel bbb ccc=0 mes "start" repeat 10 wait 50 timeGetTime : st=stat repeat 1000 //1000回繰り返し処理の経過時間取得 notesel bbb //この処理時間を計る noteget ddd,0 notedel 0 //0行目を削除 if ddd="abc" : { notesel eee : noteadd ddd,0 //"abc"なら0行目に追加 } else : notesel fff : noteadd ddd,0 //それ以外を0行目に追加 loop timeGetTime : et=stat mes ""+(cnt+1)+"回目の処理で"+(et-st)+"ミリ秒経過しました。" loop timeEndPeriod 1 stop



p、USAGI

リンク

2009/4/25(Sat) 02:37:03|NO.24796

なるほど。
KpanさんのURL先も参考になりました。
ありがとうございました。



LonelyWolf

リンク

2009/4/25(Sat) 04:38:26|NO.24800

1行目以降全てをコピーしたりの手間がありますので
0行目を消すとなると、前半で重たくなります。
getstrで1行1行処理していけば、早くなります

#include "winmm.as" timeBeginPeriod 1 mes "少しお待ちください。" aaa="abc\nxyz\n": bbb="" repeat 5000 bbb=""+bbb+""+aaa loop ccc = bbb mes "start" mes "note系" repeat 10 wait 50 timeGetTime : st=stat repeat 1000 //1000回繰り返し処理の経過時間取得 notesel bbb //この処理時間を計る noteget ddd,0 notedel 0 //0行目を削除 loop timeGetTime : et=stat mes ""+(cnt+1)+"回目の処理で"+(et-st)+"ミリ秒経過しました。" loop mes "* getstr" repeat 10 wait 50 timeGetTime : st=stat repeat 1000 //1000回繰り返し処理の経過時間取得 getstr ddd, ccc, offset offset += strsize loop timeGetTime : et=stat mes ""+(cnt+1)+"回目の処理で"+(et-st)+"ミリ秒経過しました。" loop timeEndPeriod 1 stop



p、USAGI

リンク

2009/4/25(Sat) 05:08:29|NO.24802

LonelyWolfさんもありがとうございます。
結局getstrを使った下記の形に落ち着きました。
みなさん、重ねてお礼申しあげます、ありがとうございました。

#include "winmm.as"
timeBeginPeriod 1 mes "少しお待ちください。" sdim bbb, 50001 repeat 5000 bbb+="abc\nxyz\n" loop sdim eee,strlen(bbb) sdim fff,strlen(bbb) mes "start" repeat 10 wait 10 timeGetTime : st=stat repeat 1000 //1000回繰り返し処理の経過時間取得 getstr ddd,bbb,bbb_pos,, : bbb_pos+=strsize //この処理時間を計る if ddd="abc" : { eee+=ddd+"\n" //"abc"ならeeeに追加 } else : fff+=ddd+"\n" //それ以外ならfffに追加 loop timeGetTime : et=stat mes ""+(cnt+1)+"回目の処理で"+(et-st)+"ミリ秒経過しました。" loop mes "end" pos 300,0 : mes "eee="+eee pos 400,0 : mes "fff="+fff timeEndPeriod 1 stop


余談ですが、最後の
mes "eee="+eee
mes "fff="+fff
で表示されたものが2重に・・・
画面ってループするの?



ONION software Copyright 1997-2023(c) All rights reserved.