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


HSPTV!掲示板


未解決 解決 停止 削除要請

2019
0726
mario大きなファイルの読み込みについて7解決


mario

リンク

2019/7/26(Fri) 20:55:10|NO.87947

とあるゲームでリプレイ機能を作ろうと思ってファイルにセーブするところまではできたのですが、
noteloadで読み込もうとすると読み込めることは読み込めるのですがnotegetの処理が1秒近く
かかってしまいます。
かといって配列に入れようとしても配列の呼び出しにとても時間がかかってしまいます。
読み込もうとするファイルは100〜200MB程度、50〜100万行程度です。

最初にすべて読み込もうとするとダメなんじゃないかと思って必要に応じてn行目を読み込みたい
のですが、何か上手い方法はないでしょうか?



この記事に返信する


Anonymous

リンク

2019/7/26(Fri) 21:08:52|NO.87948

ソッチ系はbload bsaveのほうが得意だった気がするぜ



mario

リンク

2019/7/26(Fri) 21:17:45|NO.87949

それも考えました

しかしbloadを使ってある特定の位置から読み込むことはできるのですが、例えば1000行目が知りたい
ときに何バイト目から読み込めばいいのかがわからないのでどうしようかと悩んでいたところです。



科学太郎

リンク

2019/7/26(Fri) 21:50:05|NO.87950

> しかしbloadを使ってある特定の位置から読み込むことはできるのですが、例えば1000行目が知りたい
> ときに何バイト目から読み込めばいいのかがわからないのでどうしようかと悩んでいたところです。
行データとバイトデータのインデックスを作れば良いでしょう。

sdim sBuff sdim sLine dim nLine dim nOffset ;解析 notesel sBuff noteload "テキストファイル.txt" repeat notemax noteget sLine,cnt nLine(cnt)=nOffset nOffset+=strlen(sLine)+2;改行分の加算 loop ;作成 sdim sBuff foreach nLine sBuff+=nLine(cnt)+"\n" loop ;保存 notesave "インデックス.txt" noteunsel
上記の「インデックス.txt」が、n行目はmバイトから始まるというオフセット値があります。
このデータを整数配列に読み込みn行目のオフセット値を「bload」命令に与えれば良いでしょう。



リンク

2019/7/26(Fri) 21:58:37|NO.87951

notegetは、常に1行目から探し始めるので、
noteget n,0;先頭から改行を探して、見つかったら終わり
noteget n,1;先頭から探して、2回改行が見つかったら終わり
noteget n,2;3回
noteget n,3;4回
という感じで処理されるので、100万行もあると、それはもう恐ろしいループ回数になります(1+2+3+4+5+6+...+1000000)
なので連続して読む場合は、ファイルのインデックスを変数に覚えさせておいて、そこからinstrで改行を探し、見つかったところまでを取り出し、改行の位置+2のところにインデックスを移動させ(CRLF)…ということをやる必要があるかもしれません。
100万行もあると、配列に突っ込むのもちょっと現実的でないです(HSPはリストではなく配列なので…)。



ドナルド

リンク

2019/7/26(Fri) 22:01:39|NO.87952

こういうのにデータベース使うのとかってアリなのかな?



Velgail

リンク

2019/7/26(Fri) 23:27:42|NO.87953

1行あたりのデータを固定長にすると、bsave, bloadでも問題なく使えます。但し容量はエグいです。

SQLite(sqlele.hsp)の使用もアリでしょう。数値データを文字列変数に無理やり詰め込むことなく、最適なサイズで入れることが出来ますから。



mario

リンク

2019/7/27(Sat) 08:14:13|NO.87955

皆さんご回答ありがとうございます。

データベースは難しそうなので配列にインデックスを保存しておくことにしました。
一応ソースを貼っときます。

filename="テキスト.txt"
//noteloadする //ただしnotegetするととても重い notesel note noteload filename sdim notes,1024,notemax dim index,notemax exist filename if strsize=-1 : end size=strsize //すべての行の始まりのインデックスを取得 t=0 repeat notemax-1 index(cnt+1)=instr(note,t,"\n")+t+2 t=index(cnt+1) await 0 loop //以下読み取り t=10000 repeat 10000 bload filename,nline,index(t+1)-index.t,index.t loop mes nline



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