C++相談室 part136

レス数が950を超えています。1000を超えると書き込みができなくなります。
2018/06/07(木) 23:40:12.36ID:GNQuDMaA0
次スレを立てる時は本文の1行目に以下を追加して下さい。
!extend:on:vvvvv:1000:512

C++に関する質問やら話題やらはこちらへどうぞ。
ただし質問の前にはFAQに一通り目を通してください。
IDE (VC++など)などの使い方の質問はその開発環境のスレにお願いします。

前スレ
C++相談室 part135
https://mevius.5ch.net/test/read.cgi/tech/1522495206/

このスレもよろしくね。
【初心者歓迎】C/C++室 Ver.102【環境依存OK】
http://mevius.5ch.net/test/read.cgi/tech/1509780815/

■長いソースを貼るときはここへ。■
 http://codepad.org/
 https://ideone.com/

[C++ FAQ]
https://isocpp.org/wiki/faq/
http://www.bohyoh.com/CandCPP/FAQ/ (日本語)

----- テンプレ ここまで -----
VIPQ2_EXTDAT: default:vvvvv:1000:512:----: EXT was configured
2018/07/10(火) 07:26:16.92ID:wSs+8Os00
A
1カラム目と2カラム目は同じ数字?
1カラム目がxの個数、2カラム目がyの個数?

C
y 2 4 の後、データ行が2行だけど4行の間違い?
データ行の値の範囲は?
2018/07/10(火) 07:29:57.69ID:U8fm2Of7a
section_nameは重複しますか?
2018/07/10(火) 07:31:15.21ID:wSs+8Os00
初めて開くファイルは使いやすいように変換して(キャッシュとして)保存しておいて
次回以降それを使うか
全ファイルバッチ処理で事前に変換しておくか

かな

ファイルを開く度に分オーダーかかるのは使いづらい
どちらが良いかは使い方次第で
2018/07/10(火) 07:49:59.14ID:wSs+8Os00
15GBオーダーのファイルがすでにいつくかあって
今後も増えるってことで良いんですよね?
2018/07/10(火) 07:55:16.04ID:wSs+8Os00
@の行は1ファイル何行くらい?
883754 (ワッチョイ 7ff1-XcsY)
垢版 |
2018/07/10(火) 14:27:03.15ID:VT/DQ/OS0
>>873,874
ソフトが出しているログなので変えられず、並行で吐くこともできないんです…

> ワイならSECTION_NAMEごとに集計したHTMLファイルかなんかを出力するプログラムをワンパスかけてから
これも考えたのですが、元ファイルと加工したファイルが常に等価ではないので、
間違って古いままの加工ファイルを参照する事故を、全員が気にする必要が
出てくるため今は保留とし、どうしてもできない時の最終手段と考えています。
こういうご意見も新しい視点が見えたりするんでありがたいです。

>>877
こんなのをイメージしています。
====================
項目名   | 個数 ※各カラムの説明行
====================
-SECTION1  | 11200
 subname1 | 8800 ※subnameがあれば折り畳みツリー形式。なければ折り畳みなし
 subname2 | 2400
+SECTION2  |  1
+SECTION3  | 666
====================
This is pen. ※SECTION1を選択するとそれに対応するテキストをここに表示
hello world.
====================
1 2 3 4 5 6 7 ※上と同じくSECTIONに対応した数値を特定できる番号を表示
8 9 10 11 12 13 14 ※ここはHTMLぽいものにし、数字クリックでその数値をprint
....
====================
884754 (ワッチョイ 7ff1-XcsY)
垢版 |
2018/07/10(火) 14:39:44.08ID:VT/DQ/OS0
>>878
> 1カラム目と2カラム目は同じ数字?
2カラム目が何の数字かまだ把握できていません。
とりあえず1カラム目と2カラム目の数値比較を行い、違う場合はエラーにしようと思います。
> y 2 4 の後、データ行が2行だけど4行の間違い?
ご指摘の通り4行の間違いでした。
> データ行の値の範囲は?
intの範囲を超えるか?ということですか?
int(-2147483648〜2147483647)で大丈夫と思います。

>>879
ユニークな名前で重複しません。

>>880
仰る通りどちらも一長一短で、今回は874さんに回答した通り、古いキャッシュを参照する事故を防ぐため、まずはテンポラリファイルを作らないことを考えています。

>>881
ファイルは毎回更新されて新しい15GBのファイル1つをインポートします。
15GBも現在のMAXサイズなのでそのうち20GBとかのものが出てくる可能性はありますが、
そこは「読み込みをひたすら待つ」と割り切りで考えています。

>>882
@の行→100行以下
Aの行→SECTIONごとに1行出るので同じく100行以下
Bの行→SECTIONごとにせいぜい20行程度。(20行*100行=20000行)
Cの行→SECTIONごとにたまに数千万のSECTIONあり(全SECTIONだと数千万〜億超えも出てきそう)
1つのSECTIONで数千万や億になり、それ以外のSECTIONは1000以下だったり、
1千万のSECTIONが複数SECTIONになることもあります。
そしてCに対して数値行が1行〜数十行、場合によっては数百行がくるので、Cとそれにかかる数値行が支配的になると思われます。

あと忘れていましたが、テキスト行は日本語がくることもあります。
それ以外は1byte文字です。
2018/07/10(火) 18:26:12.65ID:wSs+8Os00
キャッシュせず
変換して保存しないとなると
ほとんど読み込み時間
解析はそれに比べれば速い

なので
もし高速化したければ
全読みしない方法を考えるしか

全読みの時間くらいは待てるっていうならその方が簡単だけど

読み込み15GB 30秒って異様に速いな
うちの8TB 7200rpmのHDD(内側の方) だと78秒
SSD? RAID? キャッシュ? RAMディスク?
886754 (アウアウウー Sa0b-XcsY)
垢版 |
2018/07/10(火) 18:39:22.79ID:AbfeQ9t7a
>>885
HDDだと思います。
サーバ用なので高速なんですかね。
ちなみに cat /proc/cpuinfo でCPUも調べたらXeonで20コア以上ありました。
(ハイパースレッドかもしれませんが)
〜次キャッシュも民生用CPUより多いと予想されます。
2018/07/10(火) 22:05:54.09ID:zwgBQXGGa
>>885
あと、全読みの時間は >>851 を参考にすると2分くらいにはなりそうなので、それくらいなら全然待てます。
fgets, sscanfの時は5分かかっていて、それで我慢するしかないのか、と諦めかけていたので。

評価もscanfもしないでfgets()だけで78秒なんですかね?
大きな違いはCPU、CPU内臓キャッシュ、HDD、メモリあたりと思いますが、それだけで本当に半分以下になるのか少し気になりますね。
2018/07/10(火) 23:40:47.46ID:VT/DQ/OS0
とりあえずみなさんのコードを眺めましたが初めて目にする関数だらけで自分のレベルでは全くついていけてないです。
一つ一つの関数がどんな動作をするのか調べていきます。

>>782,833 を見るとcharのポインタをインクリして読むやりかたとか昔ちらっと読んだことある。程度のレベルなので。。

今833-837の動作確認ができたので、まずはこれがどう動いているかと、バイナリ読み込みの手法について調べていきます。
2018/07/11(水) 00:11:48.47ID:Faj75qU20
>>887
fgetsじゃなくて
freadで1MBずつ読むだけで78秒
庶民の普通のHDDはこんなもんです
解析入れてもほぼ同じなので
読むのに30秒なら解析入れても30秒で終わるよ
もちろんうまく作ればだけど
2018/07/11(水) 00:15:35.84ID:Faj75qU20
>>833をマネしたら30秒じゃ無理だろうけどね
2018/07/11(水) 09:43:08.56ID:zsyvWkTI0
ここはC++スレだからstd::regex使いなよ
>>833よりは速いし安全だぞ
2018/07/11(水) 12:53:48.19ID:MaErrZw3d
速いわけが無い
コードを書いて時間を測ってみなさい
2018/07/11(水) 12:58:55.32ID:zIxL2DqcM
脳高速
2018/07/11(水) 13:08:59.82ID:MaErrZw3d
sscanfが遅くてなんとかしたい
っていう話題なのに
DBだとかhtmlだとかregexだとか
頭がおかしいのが多いな
2018/07/11(水) 13:11:36.83ID:ElMeoT060
何度も表示させたいなら、解析結果をDBに格納しておくというのもいい方法だと思うが
事前にできるなら、見かけ上の実行時間も節約できるんだし
2018/07/11(水) 13:13:59.36ID:MaErrZw3d
ちょっとは要望を読んでから書けよ
2018/07/11(水) 13:31:20.08ID:jxunhcWG0
エアプ野郎が多いからねこのスレ
何の意味があるのかは知らんが
2018/07/11(水) 13:43:15.78ID:ElMeoT060
DBって要望がチャンと出てくる前の話だろう
サーバーで動かす位しか条件書いて無かったぞ
2018/07/11(水) 14:49:25.23ID:zsyvWkTI0
>>892
ループごとにregexオブジェクト作り直して時間測ってりゃ遅くなるわな
あれは使い回すもんだよやり直し
2018/07/11(水) 15:12:40.20ID:uU0OdRlq0
(ぴこーん!) boost::spiritだな!
2018/07/11(水) 15:20:28.24ID:jxunhcWG0
うん、regexよりはspirit::qiだよね
ワッチョイ a781-UVFsは的外れにも程がある
そしてそれ以前にregexもspiritもC++初心者に勧めるようなものではない
2018/07/11(水) 16:03:49.81ID:ElMeoT060
要件が全部出ていたわけじゃないのに
エスパーが登場して的当てたのか?そりゃスゴイな
2018/07/11(水) 21:40:55.60ID:Faj75qU20
>>743の時点で低レベルな記述が適していることくらいわかるだろ
15GBのテキストだぞ
2018/07/11(水) 21:42:08.49ID:Faj75qU20
>>899
>>894
2018/07/11(水) 22:32:29.61ID:DRc50H9L0
遅いから早くしたい
どんなに頑張っても無理なら
遅くてもよい仕組みにするという手もある
2018/07/11(水) 23:31:22.90ID:Faj75qU20
そういう事は頑張ってから言え
2018/07/11(水) 23:32:32.43ID:Faj75qU20
わざわざ遅い方法を選んで「無理」とか
ただの無能
908デフォルトの名無しさん (ワッチョイ 0780-Rmg1)
垢版 |
2018/07/11(水) 23:39:25.00ID:r1UJt2Dq0
やっぱりな低学歴しかいないわ
2018/07/11(水) 23:42:02.99ID:Faj75qU20
>>908
糞コードの負け犬君の登場ですね
910デフォルトの名無しさん (ワッチョイ 0780-Rmg1)
垢版 |
2018/07/11(水) 23:43:40.24ID:r1UJt2Dq0
そもそも最初のフォーマットと全然違うやんけ
普通にfgetsでとって、必要最低限の位置をマーキングするほうが
メモリに入れるのはそれだけ

位置からメモリブロックをとって、>>834>>835みたいなやりかたで表示が必要になったときに解析
911デフォルトの名無しさん (ワッチョイ 0780-Rmg1)
垢版 |
2018/07/11(水) 23:46:44.47ID:r1UJt2Dq0
そもそも解析アプリが出力してる規定されてるフォーマットなのに
いちいち形式をチェックする必要すらない

ホントな知恵遅れはなにをいってんのか意味不明だからな
クソニートのエアプログラマがテキトーなことばっかりいってんのは分かる
2018/07/11(水) 23:51:40.60ID:7/yJo8F80
スケジュールを開始するボタンに名前をつけたいけどいい名前が思い浮かばない
できれば6文字以内で
開始とか実行はダメ
2018/07/12(木) 00:02:21.07ID:1QTfgkTp0
>>912
とりあえずC++は関係ないな
914デフォルトの名無しさん (ワッチョイ a580-lT5f)
垢版 |
2018/07/12(木) 00:09:52.26ID:LmT6lrwh0
ちなみな
fgets()は知恵遅れのキミラが考えてるよりぜんぜん速い
このスレの知恵遅れが書くようなクソコードより全然速い

書式付の標準関数は書式解析のオーバーヘッドがあるからクソ遅い
915デフォルトの名無しさん (ワッチョイ a580-lT5f)
垢版 |
2018/07/12(木) 00:14:29.53ID:LmT6lrwh0
ちなみにな手で入力したときは
fscanfやsscanfは使えない
書式より引数が少ない場合簡単に死ぬからな

手で入力してるデータの場合fgets()でデータとって丹念に解析するしかない
つまりfscanfやsscanfの使用も想定する=間違いなく妥当な形式の入力がある
ことを意味する
2018/07/12(木) 00:15:24.91ID:KB59nVpm0
同じ事を何度も書かなくて良い
>>758

あとfgetsよりfreadの方が速い
当たり前ですが
917デフォルトの名無しさん (ワッチョイ a580-lT5f)
垢版 |
2018/07/12(木) 00:17:19.69ID:LmT6lrwh0
メモリブロックとるときは
普通にfreadでいい
どうせ改行位置は解析しないといけないから
fgetsにやらせとけばいい

知恵遅れはTPOにあった関数の使い方がわかってないからな
918デフォルトの名無しさん (ワッチョイ a580-lT5f)
垢版 |
2018/07/12(木) 00:22:11.12ID:LmT6lrwh0
知恵遅れはなにをどういった場面で使うのか分かってないからな
そもそも話がかみあうワケがない

知恵遅れにありがち
電車みて電車の型番いえるだけみたいな頭悪いのが
このスレにはウヨウヨいる
2018/07/12(木) 00:22:42.68ID:KB59nVpm0
わざわざ改行検索だけの為にメモリスキャン
ガチガチにチューニングするつもりならあり得ないですね
2018/07/12(木) 00:23:57.39ID:KB59nVpm0
適度なチューニングで妥協するんであれば
fgetsで良いかも知れませんが
2018/07/12(木) 00:28:02.27ID:KB59nVpm0
freadで読む時間とほぼ同じ時間で解析まで終わるので
中途半端な解析で止める必要もなくて
直接使いやすい形にすれば良い

あとは>>885
2018/07/12(木) 00:32:07.09ID:2mlSfrk0a
>>889

なるほどですね。
解析入れてもあまり変わらないのか。
scanfって本当に遅いんですね、嬉しい誤算です。

話題に出ているregexですが、↓ここを見た感じ、

ttps://www.sejuku.net/blog/25962

下記のように感じました。
perlやpythonの正規表現と似た感じなので使えるかもしれません。
1文字づつシフトしてスペースや改行を判定しながら抽出するより早いのであれば試して見ようと思います。

regcomp →正規表現オブジェクト?の作成。()でグループ化。読み込み前にすべてのフォーマットパターンを生成して使い回す。
regexec →正規表現オブジェクトを使ってパターンマッチ
rm_so、rm_eo →マッチの先頭、終端が取れるので文字列が拾える。こんな感じ?→strncpy(&str, data+match[i].rm_so, match[i].rm_eo - match[i].rm_so);
regfree →読み込み終了後にすべてのオブジェクトをこれで開放すればいい?

spirit::qiはググりましたがまったくわかりませんでした。。
2018/07/12(木) 00:34:07.21ID:KB59nVpm0
15GBともなると
関数を呼ぶ時間でもトータル時間に影響するんでね
fgetsの関数コール回数だってバカにならんでしょ

全てのfloatをvectorにpush_backするだけでも
結構な時間ですよ
この辺も工夫しないと
924デフォルトの名無しさん (ワッチョイ a580-lT5f)
垢版 |
2018/07/12(木) 00:34:22.25ID:LmT6lrwh0
正規表現なんか使ったらコンパイル済の正規表現でも
クソ遅いにきまってるやんけ

そんなもん使うならスクリプトでやったほうがいい
925デフォルトの名無しさん (ワッチョイ b5b3-kMcx)
垢版 |
2018/07/12(木) 09:04:08.15ID:8O8kwVFO0
ディスク読むより遅いでしょうか。
2018/07/12(木) 09:40:21.55ID:yoYPGeS70
>>922
だからregexもspiritも使わなくていいってばw
すでに実例出してくれてるような昔ながらのC言語的な書き方でいいと思う
まともな実例も示さずに「○○使え」は無視していいよ
2018/07/12(木) 10:27:30.25ID:oZ8teohGM
頭使え
928デフォルトの名無しさん (ワッチョイ f1d2-LQig)
垢版 |
2018/07/12(木) 13:31:18.35ID:9k08EbFv0
ちなみに gcc (Ubuntu 7.3.0-16ubuntu3) 7.3.0 だと、 C++がちゃんとしてて、std::getline()はfread()と同じくらい速い。
各自で実際に試してみるとよいだろう。

Visual Studio だとstd::getline()はfgets()よりも遅い。
コンパイラによって性能に極端な差がでるのがC++のiostream周り。iostreamが地雷扱いされる主因。
2018/07/12(木) 14:27:06.99ID:Jbx8ub/k0
15GB なんて、もし画像ファイルなら、触った途端に、メモリ不足でフリーズするレベル。
普通、8GB ぐらいしか、メモリを積んでいないだろ

1行毎に、読んでは捨てる方式じゃないと無理。
それか、ファイル分割する

Ruby で、HTML, Node.js などが良さそう。
それか、DB
2018/07/12(木) 14:35:16.06ID:QybvZFcBd
順番にアホが書き込むスレ
2018/07/12(木) 14:43:21.06ID:QybvZFcBd
>>929
>>743から読んで出直してきなさい
2018/07/12(木) 20:53:29.39ID:KB59nVpm0
色々な言語で速度比較とか面白そう
2018/07/12(木) 21:42:21.02ID:KB59nVpm0
>>871のフォーマットでC++で作ったら
解析15GBで8.6秒
1バイト平均2クロック!

これを越えるには
マルチスレッド / AVX命令 /アセンブラ / GPU
に手を出さないと無理かな

----
Haswell
3.4GHz固定
シングルスレッド
C++で1文字ずつ15G文字解析
普通の命令のみ使用(SIMD命令は使用しない)
数値の合計のみ計算して結果を最後に表示
固定4KBを繰り返し解析、トータル15GB分の時間を計測
----
2018/07/12(木) 21:55:17.33ID:Ze/sD5Dv0
1ブロック内に数値が数万あってどうUIで表示すんのか気になる
2018/07/12(木) 22:00:17.37ID:KB59nVpm0
数値ならグラフにするとか画像にするとかフィルターを通してから間引くとか音声にして鳴らすとか
まあ色々とあると思う
2018/07/12(木) 22:08:43.66ID:8VUYfWV40
>>926
おとなしく1文字づつ評価します。

>>933
8.6秒早いですね。

自分はまず初バイナリ読み込みなので勉強から始めてとりあえず1行読みができましたが、
アスキー読み込みのfgetsの方が早かったです、、
コードを載せるのでどこが悪いか見てもらって良いですか?

対象=13GBのファイル(約8億行)。

○fgets版 →約17秒
if((fp=fopen(file_path,"r"))==NULL){
  printf("file not open %s\n", file_path);
 return 1;
}
while( fgets(buf,MAX,fp) != NULL ){
 buf;
}

次にバイナリ読み↓
2018/07/12(木) 22:11:04.95ID:8VUYfWV40
○バイナリ読み版 →約44秒
struct CCC {
 FILE *fp ;
 bool read(char* file_path);
 t_read_db read_db;
};
bool CCC::read(char file_path[]){
 FILE *fp;
 if((fp=fopen(file_path, "rb"))==NULL){ printf("ファイルを開けません。%s",file_path); return 0; }
 unsigned char buf[BUF_SIZE];
 int newline_index;
 while( !feof( fp ) ){
  size_t size = fread( &buf, sizeof(buf[0]), sizeof(buf), fp );
  // 終端処理。最大値で取得されてなければそこを末尾にする
  if( size != BUF_SIZE ) buf[size] = '\x00';
  // 取得bufの最後尾が改行でなければfpを改行まで戻す
  if( buf[size-1] != '\x0a' ){
   newline_index = -2;
   for(; buf[size+newline_index] != '\x0a'; --newline_index);
   fseek(fp,newline_index+1,SEEK_CUR);
   // bufの最後の改行の次にx00(null)を入れてそれ以降をカット
   // 「配列参照はポインタの移動より遅い」とあったがbufは実体で移動できないので[]参照で代入。
   buf[size+newline_index+1] = '\x00';
  }
  unsigned char const* c_buf = buf;
  while( c_buf[0] != '\x00' ){
   print_line(c_buf, &c_buf);
  }
 }
}
2018/07/12(木) 22:11:35.38ID:8VUYfWV40
bool print_line(unsigned char const* p_buf, unsigned char const** pct_next);
bool print_line(unsigned char const* p_buf, unsigned char const** pct_next){
 unsigned char const* c_buf = p_buf;
 //改行位置を検索
 for(; *c_buf != '\x0a'; ++c_buf);

 char line[LINE_SIZE];
 strncpy( line, (char const*)p_buf, c_buf - p_buf );
 // nullで区切らないと過去に代入した文字数より少ないときにゴミが残る
 line[c_buf - p_buf] = '\x00';

 ++c_buf;
 *pct_next = c_buf;
 return true;
};
2018/07/12(木) 22:13:44.64ID:8VUYfWV40
○fgets版 →約17秒
○バイナリ読み版 →約44秒

両方ともとりあえず文字列の読み取りまでしていて、条件は同じではないかと思うのですが、freadのほうが倍以上遅いです。。
2018/07/12(木) 22:14:27.55ID:oZ8teohGM
>>936
setvbufはしないの?
2018/07/12(木) 22:15:24.64ID:Ze/sD5Dv0
>>935
fgetsで悩んでる人がそのハードル超えることできるか心配してるんですよ
2018/07/12(木) 22:17:52.40ID:8VUYfWV40
すみません、44秒はfreadの読み込みサイズ(BUF_SIZE)が512byteでした。
16MBにすると34秒になりましたが、それでも倍の差があります。
2018/07/12(木) 22:33:29.40ID:oZ8teohGM
>>942
mmapがいるかなぁ
BSD grep のソースのコメントにこの辺りの高速化の
コツが書いてあるので一読されたし
2018/07/12(木) 23:04:55.64ID:8VUYfWV40
>>943
mmapですか。
要チェックですかね。
でもそれだけで数倍早くなるとも思えないし、 >>933 さんの8.6秒は圧倒的パフォーマンスですね。
シングルスレッドで特殊なものは使ってないようだし、たった4KBの繰り返しだし。
根本的なところから違いそう。。

>>933
もし可能であれば、テストしたコードを見せていただくことはできませんでしょうか?
945デフォルトの名無しさん (ワッチョイ a580-lT5f)
垢版 |
2018/07/12(木) 23:10:07.38ID:LmT6lrwh0
あのな
そこまで読みこみ速度を気にするなら
そもそもFILEポインタ使う関数なんか使うなよ
そもそもFILEポインタ使う関数はバッファリングしてるから
いちいちメモリコピーしてんのに

そこまでガタガタいうなら
openとreadで普通にメモリブロック読みこむ処理にしろよ
ハゲ
2018/07/12(木) 23:13:14.06ID:8VUYfWV40
>>940,941
setvbufも初耳です。
941さんのコメントからすると、これまた難しそう。。

色々と情報ありがとうございます。
947デフォルトの名無しさん (ワッチョイ a580-lT5f)
垢版 |
2018/07/12(木) 23:13:42.35ID:LmT6lrwh0
ちなみになFILEポインタは構造体にファイルデスクリプタもってる
fopenでopenを呼び出してファイルディスクリプタ生成して構造体に保存してる
ファイル読むときはファイルディスクリプタでread使ってバッファリングしながら読みこんでる

このスレの低学歴どもはこういう基本的なことわかってんの
948デフォルトの名無しさん (ワッチョイ a580-lT5f)
垢版 |
2018/07/12(木) 23:15:00.75ID:LmT6lrwh0
そのsetvbufというのが
バッファリングするバッファのサイズだ
つまり、バッファにたまったメモリをひたすらコピーしてる
2018/07/12(木) 23:15:52.81ID:oZ8teohGM
filenoとfdopenの理解はデフォ
950デフォルトの名無しさん (ワッチョイ a580-lT5f)
垢版 |
2018/07/12(木) 23:18:11.64ID:LmT6lrwh0
32bit越えるmmapとか
そんなやばそうなもん使うのか
まずちゃんと動作するか確認することになるわ
951デフォルトの名無しさん (ワッチョイ a580-lT5f)
垢版 |
2018/07/12(木) 23:31:34.69ID:LmT6lrwh0
休日にオレのエレガントなファイル読みこみ処理作ってやるから
楽しみにしてなさい
2018/07/12(木) 23:40:59.34ID:KB59nVpm0
HDDの一番外側15GB
セクタ直読みで60.1秒
平均 250MB/s でした

7200rpmの8TBのHDDです
2018/07/12(木) 23:44:58.13ID:KB59nVpm0
>>851の77.9秒はHDDの内側の方でfreadでの読み込み
どちらもHDDの限界と思います
2018/07/12(木) 23:49:15.37ID:KB59nVpm0
>>944
解析時間のほとんどが>>782のようなコードです
ちょっと変えましたが
2018/07/12(木) 23:53:49.46ID:KB59nVpm0
改行を探す為だけにスキャンする必要はありませんし、コピーする必要もありません

ほとんどをしめる数値の行は
>>782の処理で区切りまでポインタが進みます
2018/07/13(金) 00:20:28.77ID:Zia1PITL0
>>951
ありがとうございます。楽しみにしています。

>>933,952,953
解析と読み込みを分けているんですね、8.6秒は解析で、読み込みがHDDのハード限界の60秒(高速な外側)、77.9秒(低速な内側)。
そこで >>851 の読み込み、解析合わせると78.1秒でほとんどがHDD律速ということか。

>>954,955
ご説明ありがとうございます。 >>782 の動作を調べてみます。
freadの扱いで質問なのですが、byte単位で取得すると最後尾が改行ではなく途中で終わることがあるので、
改行区切りになっているdata変数がだと思って、937に書いたコードでは、自分がわかる知識で考えて、
freadで読み込んだあとに改行のところまでfseekで戻しているんですが、この考え方はあっているのでしょうか?
2018/07/13(金) 00:21:42.58ID:Zia1PITL0
data変数がだと思って →×
data変数が必要だと思って →○
2018/07/13(金) 00:28:02.06ID:Zia1PITL0
>>952
すみません、あと、 >>936 に書いているfgets版のコードだとどれくらいの速度が出ていますでしょうか?
fgetsで回したものと fread + >>782 のコードでどれくらいの比率になるのか気になりました。
959デフォルトの名無しさん (ワッチョイ f1d2-LQig)
垢版 |
2018/07/13(金) 01:21:45.76ID:5Z2wrzxE0
MS製の金毘羅でfgets(), fgetc()を試す場合は、_CRT_DISABLE_PERFCRIT_LOCKS 必須で。
2018/07/13(金) 02:19:38.68ID:AZAPUt/l0
無能な働き者が書いた半角スクリプトなんて誰も走らせたくない
2018/07/13(金) 06:36:46.59ID:vZSq0WGS0
毎回fseekで改行位置まで戻してたら意味ねー
2018/07/13(金) 07:08:38.04ID:n6X2CtBj0
>>956
読み込みの境目の処理方法はいくつかあります

A. 1行全体が連続してバッファに存在しなくてもいい作りにする
B. リングバッファ
C. fseekでファイルポインタを戻してから読み込む
D. あまりをmemcpyでバッファの先頭にコピーしてから読み込む
E. ほか

読み込み単位が大きければ C. or D. のコストは無視出来るので C. D. で
読みこみ単位が小さければ A. B. なども考える
といった感じかと思います

今回私は解析処理が簡単に作れて、HDDの読み込みに一切影響を与えない、D.で作りました
2018/07/13(金) 08:06:32.03ID:n6X2CtBj0
>>958
fread
fgets
ReadFile

読み込みだけだとどれも78秒
964754 (ワッチョイ 66f1-yKfk)
垢版 |
2018/07/13(金) 11:12:41.59ID:Zia1PITL0
>>959
ttp://ftp.tsukuba.wide.ad.jp/software/gcc/releases/gcc-8.1.0/gcc-8.1.0.tar.xz
これを使ってるので、まずはMSのオプションは関係なさそうです。
でもMSのコンパイラは早いという記事をこの前読んだのでそっちの方に乗り換えた方がいいのかな。
完成した後に両方テストして良好な方を検討しようと思います。

>>962,963
A,Bは難易度高そうですね。
Cは自分がやった手法のようですが、Dはポインタを戻す分の再取得が無いのでCより良さそうに見える。
Dを検討してみます。

fgetsもfreadも同じ時間ですか。
となるとfgets 13GB 17秒だから、そのレベルの速度は出るはずなのか。

今782のコードを調べて動作がわかってきました。
char演算で文字コードを数字の始点に移動させ9以下で数字以外(スペースor改行)を判定。
*10で桁を表現し、文字コードの番号で演算。(文字→数字変換していない!!)
このファイルで支配的な数字行が文字→数字変換が一度もないおかげですごく効きそう。
原理がわかるとなるほど!となるけど、1桁ずつ演算、文字コード演算は自分がやってたら絶対にたどり着かない発想です。
2018/07/13(金) 11:27:35.12ID:oo2UOY380
text/byte stream は異なる。
文字列はバイトじゃなく、テキスト

バイトは構造体など、構造が決まっているもの

改行区切りで、改行の位置が変わるものは、テキスト処理
2018/07/13(金) 12:02:35.45ID:cfQ/Db/gp
>>965
お前ちょっと黙っとけ
2018/07/13(金) 12:51:36.83ID:dS91uWOz0
可変長構造体なんてのもあったりして
2018/07/13(金) 16:34:16.85ID:oo2UOY380
通信データなどは、可変長構造体

ヘッダーなどは固定サイズで、データ部分は可変サイズ。
可変部分のサイズが、ヘッダーなどに書いてある
2018/07/13(金) 17:51:00.86ID:k5yNhwQP0
gcc拡張でサイズ0の配列定義うんたら
2018/07/13(金) 19:10:12.44ID:wVklUpFP0
>>969
C99なら規格化されたのでgcc拡張は要らなくなった
2018/07/13(金) 20:14:02.67ID:Zuzc5Uab0
C99の可変長配列はC++には取り入れられなかったし、
C11ではオプションに格下げされたんじゃなかったっけ?

年式でフラフラする機能の典型例のような記憶がある。
2018/07/13(金) 20:48:09.66ID:ZWzFkIpgd
おまいらスレタイ
2018/07/13(金) 20:52:43.56ID:wVklUpFP0
>>971
可変長配列(VLA)については、そのとおり
しかし >>970 >>969 で指しているのは、構造体内の 0 長配列メンバ、または C FAQ 2.6
2018/07/13(金) 20:56:12.79ID:dep+wTpc0
>>971
VLA のことと誤解してないか?
ここで言ってる「可変長構造体」は構造体の最後の要素が不完全型であることを許すルールのことだと思う。

struct a {
int a;
int b[];
};

このとき sizeof(struct a) は要素 b を含まない大きさを返す。
malloc(sizeof(struct a)+(bの大きさとして確保したい大きさ)) とすれば b が可変長な構造体として使える。

このルールが出来る前 (C89) は仕様に沿ってこのようなことをしようと思うと
配列 b の大きさを便宜上 1 として指定しておく、
つまりは

struct a {
int a;
int b[1];
};

としておいて malloc のサイズ指定のときに要素一個分の大きさを差し引いて調整するようなことをしていた。
2018/07/13(金) 20:59:38.81ID:n6X2CtBj0
どうでもいい機能
2018/07/13(金) 21:06:27.07ID:Zuzc5Uab0
すまん、皆の言う通りだ。ちゃんと読めば
構造体の末尾メンバの0サイズ配列の話だと分かる流れだったのに、
なんでか裸の配列の要素数だと思いこんでしまった。
2018/07/14(土) 01:43:04.14ID:6fifTYMf0
GCC拡張をしたとして
struct a {
 int b[0];
};
のsizeof(a)はいくつなんじゃろうか…
レス数が950を超えています。1000を超えると書き込みができなくなります。
5ちゃんねるの広告が気に入らない場合は、こちらをクリックしてください。

ニューススポーツなんでも実況