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



記事削除

記事NO.パスワード
(質問が解決したスレッドは他の利用者に活用してもらうため、削除しないようお願いします)

NO.87947への返信

マスコット

好きなマスコットを選んでください。

名前

e-mail
HOME
  1. 初めて利用する方は、HSP3掲示板の使い方をお読みください。
  2. 不要部分の多い長いスクリプトの投稿は ご遠慮ください。
  3. 書き込みは自動改行されません。適度に改行を入れてください。
  4. スクリプトは小文字の<pre>〜</pre>で囲むと見やすく表示できます。

削除用パスワード

解決したら質問者本人がここをチェックしてください。

エラー発生時、再送信すると二重送信になることがあります。
回答が得られたら、お礼書き込み時に[解決]チェックしてください。
SPAM防止のためURLから始まる文章は投稿できません。
SPAM防止のため英文字のみの本文を投稿することはできません。

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