トップページ > プログラム > 2018年07月12日 > 8VUYfWV40

書き込み順位&時間帯一覧

4 位/174 ID中時間01234567891011121314151617181920212223Total
書き込み数0000000000000000000000527



使用した名前一覧書き込んだスレッド一覧
754 (ワッチョイ 66f1-Y8gp)
C++相談室 part136

書き込みレス一覧

C++相談室 part136
936 :754 (ワッチョイ 66f1-Y8gp)[sage]:2018/07/12(木) 22:08:43.66 ID: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;
}

次にバイナリ読み↓
C++相談室 part136
937 :754 (ワッチョイ 66f1-Y8gp)[sage]:2018/07/12(木) 22:11:04.95 ID: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);
  }
 }
}
C++相談室 part136
938 :754 (ワッチョイ 66f1-Y8gp)[sage]:2018/07/12(木) 22:11:35.38 ID: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;
};
C++相談室 part136
939 :754 (ワッチョイ 66f1-Y8gp)[sage]:2018/07/12(木) 22:13:44.64 ID:8VUYfWV40
○fgets版 →約17秒
○バイナリ読み版 →約44秒

両方ともとりあえず文字列の読み取りまでしていて、条件は同じではないかと思うのですが、freadのほうが倍以上遅いです。。
C++相談室 part136
942 :754 (ワッチョイ 66f1-Y8gp)[sage]:2018/07/12(木) 22:17:52.40 ID:8VUYfWV40
すみません、44秒はfreadの読み込みサイズ(BUF_SIZE)が512byteでした。
16MBにすると34秒になりましたが、それでも倍の差があります。
C++相談室 part136
944 :754 (ワッチョイ 66f1-Y8gp)[sage]:2018/07/12(木) 23:04:55.64 ID:8VUYfWV40
>>943
mmapですか。
要チェックですかね。
でもそれだけで数倍早くなるとも思えないし、 >>933 さんの8.6秒は圧倒的パフォーマンスですね。
シングルスレッドで特殊なものは使ってないようだし、たった4KBの繰り返しだし。
根本的なところから違いそう。。

>>933
もし可能であれば、テストしたコードを見せていただくことはできませんでしょうか?
C++相談室 part136
946 :754 (ワッチョイ 66f1-Y8gp)[sage]:2018/07/12(木) 23:13:14.06 ID:8VUYfWV40
>>940,941
setvbufも初耳です。
941さんのコメントからすると、これまた難しそう。。

色々と情報ありがとうございます。


※このページは、『2ちゃんねる』の書き込みを基に自動生成したものです。オリジナルはリンク先の2ちゃんねるの書き込みです。
※このサイトでオリジナルの書き込みについては対応できません。
※何か問題のある場合はメールをしてください。対応します。