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


HSPTV!掲示板


未解決 解決 停止 削除要請

2015
0203
uhoho10Mbyteくらいのcsvファイルを扱っていて、プログラムがフリーズ4解決


uhoho

リンク

2015/2/3(Tue) 18:02:23|NO.67243

ご質問させていただきます。
10MByte程度のcsvファイルを読み込んで解析するソフトを作成中なのです。
noteselで10メガオーバーのcsvを指定することはできたのですが、notegetを繰り返しているとプログラムがフリーズしてしまいます。

リソースモニタをみても、メモリには余裕があります。
HSPで大容量のcsvを扱うことはできないのでしょうか?



この記事に返信する


kanahiron

リンク

2015/2/3(Tue) 18:37:58|NO.67245

試しに10MBのcsvデータを作ってnotegetしてみましたが重くなるなどの動作はありませんでしたよ

#const csvsize 10*1024*1024 randomize 0xF0F0F0F0 sdim csv,csvsize+128 sdim data,csvsize*10 sdim temp2,64,10 temp = "" len = 0 index = 0 repeat temp = strf("%d,",rnd(32767)) len = strlen(temp) memcpy csv,temp,len,index,0 index += len if cnt \ 10 = 0{ wpoke csv,index,0x0A0D index += 2 } if index >= csvsize:break loop mes "10MBのCSVを作成しました" len = 0 index = 0 temp = "" notesel csv mes ""+noteinfo(0)+"行です" pos 0,50 mesbox data,640,430 repeat noteinfo(0) //長いので100行ずつ読み出します if cnt \ 100 != 0{ continue } ccnt = cnt noteget temp,cnt split temp,",",temp2 repeat 10 temp = strf("%d行目 %d番目=%d\n",ccnt,cnt,temp2(cnt)) len = strlen(temp) memcpy data,data,index,len,0 memcpy data,temp,len,0,0 index += len loop objprm 0,data await loop
この場合は1つの要素が5B程度しかありませんが、64Bを超える場合は予めsdimで確保した方がいいと思います(上記だと変数temp)



cats

リンク

2015/2/3(Tue) 18:55:53|NO.67246

巨大なデータをメモリ上に展開するのは非常に好まれない手法です。
bload, bsaveを使って少しずつ読み込んでいくなどした方がいいです。
全データを一気に表示させるようなソフトなら仕方無いですが、指定させた部分を解析するようなソフトなら、
予めデータごとのオフセットだけを記録しておいて、データを使うときにそのオフセットを参照するようにすればよいです。



Flat

リンク

2015/2/3(Tue) 19:37:08|NO.67248

notegetで全行取得するとかなり重いです
splitで配列にばらしてしまうと高速化できるかと。

ちなみに、元データが変数aに入っていて、各行を配列bに入れる場合は
split a, "\n", b
とします。



uhoho

リンク

2015/2/4(Wed) 10:59:49|NO.67259

たくさんのご返答ありがとうございます。
ソースまで書いていただいていながら、お恥ずかしい話なのですが、正しく動作しなかった理由はawaitの入れ忘れでした。
しかしながら、csvの取り扱いについてたくさんのヒントがいただけましたので、プログラムを改良することができました。
memcpyの使い方がわかったのは大きな成果でした。過去に作ったソフトも高速化できそうです。

大変ありがとうございました!!!



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