C++相談室 part136

レス数が1000を超えています。これ以上書き込みはできません。
0001デフォルトの名無しさん (ワッチョイ bf81-LHz9)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

0952デフォルトの名無しさん (ワッチョイ 3d50-Se03)2018/07/12(木) 23:40:59.34ID:KB59nVpm0
HDDの一番外側15GB
セクタ直読みで60.1秒
平均 250MB/s でした

7200rpmの8TBのHDDです

0953デフォルトの名無しさん (ワッチョイ 3d50-Se03)2018/07/12(木) 23:44:58.13ID:KB59nVpm0
>>851の77.9秒はHDDの内側の方でfreadでの読み込み
どちらもHDDの限界と思います

0954デフォルトの名無しさん (ワッチョイ 3d50-Se03)2018/07/12(木) 23:49:15.37ID:KB59nVpm0
>>944
解析時間のほとんどが>>782のようなコードです
ちょっと変えましたが

0955デフォルトの名無しさん (ワッチョイ 3d50-Se03)2018/07/12(木) 23:53:49.46ID:KB59nVpm0
改行を探す為だけにスキャンする必要はありませんし、コピーする必要もありません

ほとんどをしめる数値の行は
>>782の処理で区切りまでポインタが進みます

0956754 (ワッチョイ 66f1-Y8gp)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で戻しているんですが、この考え方はあっているのでしょうか?

0957754 (ワッチョイ 66f1-Y8gp)2018/07/13(金) 00:21:42.58ID:Zia1PITL0
data変数がだと思って →×
data変数が必要だと思って →○

0958754 (ワッチョイ 66f1-Y8gp)2018/07/13(金) 00:28:02.06ID:Zia1PITL0
>>952
すみません、あと、 >>936 に書いているfgets版のコードだとどれくらいの速度が出ていますでしょうか?
fgetsで回したものと fread + >>782 のコードでどれくらいの比率になるのか気になりました。

0959デフォルトの名無しさん (ワッチョイ f1d2-LQig)2018/07/13(金) 01:21:45.76ID:5Z2wrzxE0
MS製の金毘羅でfgets(), fgetc()を試す場合は、_CRT_DISABLE_PERFCRIT_LOCKS 必須で。

0960デフォルトの名無しさん (ワッチョイ ea34-7KrU)2018/07/13(金) 02:19:38.68ID:AZAPUt/l0
無能な働き者が書いた半角スクリプトなんて誰も走らせたくない

0961デフォルトの名無しさん (ワッチョイ 0a4c-E8X4)2018/07/13(金) 06:36:46.59ID:vZSq0WGS0
毎回fseekで改行位置まで戻してたら意味ねー

0962デフォルトの名無しさん (ワッチョイ 3d50-Se03)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.で作りました

0963デフォルトの名無しさん (ワッチョイ 3d50-Se03)2018/07/13(金) 08:06:32.03ID:n6X2CtBj0
>>958
fread
fgets
ReadFile

読み込みだけだとどれも78秒

0964754 (ワッチョイ 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桁ずつ演算、文字コード演算は自分がやってたら絶対にたどり着かない発想です。

0965デフォルトの名無しさん (ワッチョイ 119e-dYrz)2018/07/13(金) 11:27:35.12ID:oo2UOY380
text/byte stream は異なる。
文字列はバイトじゃなく、テキスト

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

改行区切りで、改行の位置が変わるものは、テキスト処理

0966デフォルトの名無しさん (ササクッテロ Spbd-mkVh)2018/07/13(金) 12:02:35.45ID:cfQ/Db/gp
>>965
お前ちょっと黙っとけ

0967デフォルトの名無しさん (ワッチョイ 118a-3Xuk)2018/07/13(金) 12:51:36.83ID:dS91uWOz0
可変長構造体なんてのもあったりして

0968デフォルトの名無しさん (ワッチョイ 119e-dYrz)2018/07/13(金) 16:34:16.85ID:oo2UOY380
通信データなどは、可変長構造体

ヘッダーなどは固定サイズで、データ部分は可変サイズ。
可変部分のサイズが、ヘッダーなどに書いてある

0969デフォルトの名無しさん (ワッチョイ 6d02-+/lp)2018/07/13(金) 17:51:00.86ID:k5yNhwQP0
gcc拡張でサイズ0の配列定義うんたら

0970 ◆QZaw55cn4c (ワッチョイ 4a60-Y8gp)2018/07/13(金) 19:10:12.44ID:wVklUpFP0
>>969
C99なら規格化されたのでgcc拡張は要らなくなった

0971デフォルトの名無しさん (ワッチョイ 3d93-x/6u)2018/07/13(金) 20:14:02.67ID:Zuzc5Uab0
C99の可変長配列はC++には取り入れられなかったし、
C11ではオプションに格下げされたんじゃなかったっけ?

年式でフラフラする機能の典型例のような記憶がある。

0972デフォルトの名無しさん (スップ Sd0a-Se03)2018/07/13(金) 20:48:09.66ID:ZWzFkIpgd
おまいらスレタイ

0973 ◆QZaw55cn4c (ワッチョイ 4a60-Y8gp)2018/07/13(金) 20:52:43.56ID:wVklUpFP0
>>971
可変長配列(VLA)については、そのとおり
しかし >>970 >>969 で指しているのは、構造体内の 0 長配列メンバ、または C FAQ 2.6

0974はちみつ餃子 ◆8X2XSCHEME (ワッチョイ 5e6f-LQig)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 のサイズ指定のときに要素一個分の大きさを差し引いて調整するようなことをしていた。

0975デフォルトの名無しさん (ワッチョイ 3d50-Se03)2018/07/13(金) 20:59:38.81ID:n6X2CtBj0
どうでもいい機能

0976971 (ワッチョイ 3d93-x/6u)2018/07/13(金) 21:06:27.07ID:Zuzc5Uab0
すまん、皆の言う通りだ。ちゃんと読めば
構造体の末尾メンバの0サイズ配列の話だと分かる流れだったのに、
なんでか裸の配列の要素数だと思いこんでしまった。

0977デフォルトの名無しさん (ワッチョイ eabd-CB8p)2018/07/14(土) 01:43:04.14ID:6fifTYMf0
GCC拡張をしたとして
struct a {
 int b[0];
};
のsizeof(a)はいくつなんじゃろうか…

0978はちみつ餃子 ◆8X2XSCHEME (ワッチョイ 5e6f-LQig)2018/07/14(土) 02:09:53.78ID:Eblv1Llg0
>>977
ゼロが返ってきたぞ。

ただし、 C/C++ におけるオブジェクトはメモリの一部を占有するものでありポインタで示せるものという要求があるので、
それと矛盾なく使うには色々と気を付けないといけないかもしれない。

ちなみに、クラスのメンバにストレージを割り当てないこと (要するにサイズゼロのオブジェクト) を許す [[no_unique_address]] という属性が C++20 で追加されてる。

0979デフォルトの名無しさん (ワッチョイ 9e9f-juwT)2018/07/14(土) 09:04:29.47ID:5xFWH4XP0
そんなクソみたいな使い方しかされない機能入れるなよ。。

0980デフォルトの名無しさん (ブーイモ MM8e-4qXr)2018/07/14(土) 09:13:37.39ID:J4NDnBASM
複数回allocateを抑制するための機能(関数)はc++にもたくさんあるじゃない

0981デフォルトの名無しさん (ワッチョイ 7db3-mkVh)2018/07/14(土) 10:41:27.91ID:uSYNDUAh0
>>979
非staticなメンバを一つも持たない上、そのクラスのポインタを扱わない(=多態性を必要としない)のに
継承したりメンバとして持ったときに1バイト追加されるのがうざいからだろ

0982デフォルトの名無しさん (ワッチョイ eabd-CB8p)2018/07/14(土) 11:49:09.59ID:6fifTYMf0
>>978
ええー!!!
struct c {
};
のsizeof(c)は1だった(と思った!)が!!

0983デフォルトの名無しさん (ワッチョイ 3a7e-LQig)2018/07/14(土) 12:04:14.50ID:xT/OvOUN0
最適なプログラムを書く必要のない立場の雑魚は黙ってろよw

0984デフォルトの名無しさん (ワッチョイ 89de-juwT)2018/07/14(土) 12:33:16.17ID:2h2LuDt30
>>981
static なメンバしかない、しかもポリモルフィズムしない(interfaceな使い方でもない)
ってそもそも継承するのが設計として間違いじゃねーの?

0985デフォルトの名無しさん (ブーイモ MMc9-LQig)2018/07/14(土) 12:41:29.77ID:l5rGqYSnM
c++つかってるとロジックやアルゴリズムなどの本来の目的より
こういう横道にそれた話題ばかりになることが多い
手段が目的化するので困る

0986デフォルトの名無しさん (ブーイモ MMc9-LQig)2018/07/14(土) 12:42:59.00ID:l5rGqYSnM
関心の集中の先はプログラムで実現できることになるべきだけど
c++はそっちより言語自信や仕様や実装に目が向く
時間が無駄に費やされやすい

0987デフォルトの名無しさん (ワッチョイ 3a7e-LQig)2018/07/14(土) 12:50:50.32ID:xT/OvOUN0
最適なプログラムを書くのもC++の目的だ
ロジック以外のことに目をそらしたいなら他の言語を使え

0988デフォルトの名無しさん (ブーイモ MMc9-LQig)2018/07/14(土) 12:53:19.80ID:l5rGqYSnM
c++は幅広い書き方ができてしまうのが一番困ったところ
10年前のコードが完全に動いてるにも拘わらずゴミに見えてしまう

0989デフォルトの名無しさん (ワッチョイ 7db3-mkVh)2018/07/14(土) 12:54:52.71ID:uSYNDUAh0
>>984
非staticなメンバが無い、ってのはメンバ変数ね(非staticなメンバ関数はあっても関係ない、つまりインターフェースも含む

0990デフォルトの名無しさん (ワッチョイ 66f1-Y8gp)2018/07/14(土) 12:55:49.99ID:FOAGvAbs0
次スレ作成のルールってどうなってますか?

0991デフォルトの名無しさん (スップ Sd0a-Se03)2018/07/14(土) 13:40:31.81ID:xV7EJA5wd
>>985
5chが異常なだけ

0992デフォルトの名無しさん (ワッチョイ a580-lT5f)2018/07/14(土) 13:55:09.44ID:1N2GRIlb0
linuxと聞いてた(>>743)のになんでMSのコンパイラの話がでてんねんと

まず実機でコレ走らせて試験をしなさい

@ 下のソースをコンパイルしてbaka_testという名前の実行オブジェクトをつくりなさい

 linuxなら↓こっち
 https://ideone.com/e9iA5m

 windowsなら↓こっち
 https://ideone.com/D4T1zh

A で、こんな試験をする
 https://ideone.com/82BnFZ

ちなみにwindowsはバッファサイズを
セクタバイト数の倍数でないとちゃんと動作しない
それはwindowsの仕様だからな(メモリアドレスはmallocで返ってくる先頭のポインタオフセットで問題ないことは分かってる)

バッファサイズを何バイトにするのが読みこみで効果的か
決めたほうがいい
試験結果をちゃんと報告するようにな

 あとOSは64bitでいいんだな
 それによっても話がかわってくる

0993デフォルトの名無しさん (ワッチョイ a580-lT5f)2018/07/14(土) 14:04:41.54ID:1N2GRIlb0
ちなみにwindowsでopenとかread使うのはクルクルパーだからな
msのランタイムがウンコなのは有名だからな

msウンコランタイムのopenでCreateFile呼び出してる
msウンコランタイムのfopenでopen呼び出してる

msウンコランタイムのreadでReadFile呼び出してる
msウンコランタイムのfgetsやfreadでread呼び出してる

わかった?

0994デフォルトの名無しさん (ワッチョイ 66f1-Y8gp)2018/07/14(土) 15:10:33.64ID:FOAGvAbs0
>>993
ありがとうございます。

g++ -o baka_test $file_name
echo 512,`./baka_test $input 512` > baka_result.txt
echo 1024,`./baka_test $input 1024` >> baka_result.txt


上記を13GBのファイルで試したら下記結果が出ました。

512,13
1024,7
2048,5
4096,3
8192,2
16384,2
32768,2
65536,2
131072,1
262144,3
524288,2
1048576,2
2097152,2
4194304,2
8388608,2
16777216,3
33554432,2
67108864,3
134217728,3
268435456,3
536870912,3
1073741824,3

0995デフォルトの名無しさん (ワッチョイ 66f1-Y8gp)2018/07/14(土) 15:11:30.95ID:FOAGvAbs0
これは一度に読み込むサイズは4KBを超えると速度に影響はなく、
>>962 のC,Dパターンの場合だと、最低1行分のバッファが必要なので、
その場合、一行のバイト数のMAX値で決めれば良い。
ということでしょうか?

0996デフォルトの名無しさん (ワッチョイ a580-lT5f)2018/07/14(土) 15:28:09.27ID:1N2GRIlb0
どんだけ速いHDDやねん。。。
すでにキャッシュされてんのか

その13とか7とか5とかいう数字は
ディスク読みこみ(ディスクの内容をバッファにコピー)にかかった時間は秒だぞ
ちゃんとコード書いてmsecにして計測したほうがよかったのかもな

暇だったら、シェルで精度の高い計測値だせるように工夫しなさい
数十秒はかかると思ってたからmsecなんか考えてもなかったわ

で、実機のOSは64ビットでいいのか
ここ結構重要だからな

0997デフォルトの名無しさん (ワッチョイ a580-lT5f)2018/07/14(土) 15:31:55.15ID:1N2GRIlb0
めんどいから128Kで2秒かからない
でいいや

0998デフォルトの名無しさん (ワッチョイ 66f1-Y8gp)2018/07/14(土) 15:43:51.17ID:FOAGvAbs0
すみません忘れてましたlinux 64bitです。

> 128Kで2秒かからない
これのことですね。 →131072,1

昨日の夜(今日の朝5時)までやって >>962 のCパターンでようやく一通りファイルを
読み込めるようになりましたが、やはり速度が出ていません。

13GBファイルで確認

fgetsのみ解析なし →17秒
freadで各文字列解析、数値行の演算を行ったもの →1分超え

コード書いてて気になる箇所がいくつかあるので質問しようと思ったけどもう1000になりますね。
次スレで質問させてもらいます。

0999デフォルトの名無しさん (ワッチョイ a580-lT5f)2018/07/14(土) 15:45:39.42ID:1N2GRIlb0
なんかよく分かってもらえてないようだが
この値はブロックで読みこむ固定のバッファリングサイズ
1行分とか関係ない

プログラムではきっと
バッファリングされたメモリを解析することになる

とりあえず今回は、必ず128K単位で読みこむ
128K単位のメモリを
正直もっと増やしてもいいとは思う

あととりあえず行の最大バイト数は256バイトで十分でいいや

1000デフォルトの名無しさん (ワッチョイ 6aaf-iHIC)2018/07/14(土) 15:50:15.57ID:okg02gBw0
ぬるぽ

10011001Over 1000Thread
このスレッドは1000を超えました。
新しいスレッドを立ててください。
life time: 36日 16時間 10分 3秒

10021002Over 1000Thread
5ちゃんねるの運営はプレミアム会員の皆さまに支えられています。
運営にご協力お願いいたします。


───────────────────
《プレミアム会員の主な特典》
★ 5ちゃんねる専用ブラウザからの広告除去
★ 5ちゃんねるの過去ログを取得
★ 書き込み規制の緩和
───────────────────

会員登録には個人情報は一切必要ありません。
月300円から匿名でご購入いただけます。

▼ プレミアム会員登録はこちら ▼
https://premium.5ch.net/

▼ 浪人ログインはこちら ▼
https://login.5ch.net/login.php

レス数が1000を超えています。これ以上書き込みはできません。