0

C でのファイルの読み取りと書き込みでパフォーマンスの問題があります。これが私の問題と解決策ですが、遅いです。

ASCII ファイルがあり、その中のすべての行をレコードと見なします。ファイル内のある位置にある特定の数に基づいて、このファイルを 2 つに分割する必要があります。たとえば、位置 10 の数値が 0 の場合、レコードは file1 に移動し、1 の場合、レコードは file2 に移動します。

私が行ったことは、入力ファイルと、出力ファイル用の他の 2 つのファイル ストリームを開くことです。入力ファイルから1行を読み取り、比較を行い、行がfile1またはfile2に移動してから、次のレコードが読み取られます。正常に動作していますが、非常に遅いです。これをより速く行う方法をアドバイスしてください。

ファイルの読み取り方法は次のとおりです。

bytes_read = readline(infile, (void*)buffer, line_size+1);

fwrite は、ファイルへの書き込みに使用されます。ファイルのサイズは約 50 MB です。入力ファイル全体を読み取った後、ファイルは閉じられます。

4

6 に答える 6

1

あなたはそこに最速の方法を持っています!

  • どのタイプの IO を持っていますか? バッファあり/バッファなし?
  • ファイルの大きさは?
  • 行ごとに出力ファイルを開いたり閉じたりしますか、それとも開いたままにしますか?
  • 出力ファイルを探していますか?
  • どの部分が遅いですか?書きます?両方?

IO は、プログラムの遅い部分の 1 つです。一部のコードは、明らかな問題を特定するのに役立つ場合があります。

于 2012-11-30T22:45:23.283 に答える
0

ファイルから読み取る場合は、fgetsを使用することをお勧めします。これにより、次のfgetsのファイルポインタが自動的に移動します。

fseekとftellは、コードの速度を低下させています。これを試して。それははるかに速いはずです。

#include <stdio.h>
#include <stdlib.h>

int
main()
{
    char line[132];
    int line_num = 0;
    FILE *fp_r, *fp_w1, *fp_w2, *fp_w;

    fp_r = fopen("readfile", "r");
    if (fp_r == NULL) {
        printf("Could not open testfile\n");
        exit(0);
    }

    fp_w1 = fopen("writefile1", "w");
    if (fp_w1 == NULL) {
        printf("Could not open writefile1\n");
        exit(0);
    }

    fp_w2 = fopen("writefile2", "w");
    if (fp_w1 == NULL) {
        printf("Could not open writefile2\n");
        exit(0);
    }

    while (fgets(line, sizeof(line), fp_r) != NULL) {
        line_num++;

        if (*(line+9) == '0') {
            fp_w = fp_w1;
        }
        else if (*(line+9) == '1') {
            fp_w = fp_w2;
        }
        else {
            printf("Exiting - Error at line %d\n", line_num);
            exit(1);
        }

        fprintf(fp_w, line);
    }

    fclose(fp_r);
    fclose(fp_w1);
    fclose(fp_w2);

    exit(0);
}

私が使用した読み取りファイルは

01234567 0 This is the line with 0 at position 10
01234567 1 This is the line with 1 at position 10
于 2012-11-30T23:37:00.223 に答える
0

コメントで議論した後、あなたの質問に対する簡単な答えはないと思います。

何千もの大きなサイズの CSV ファイルを効果的に読み書きするのは非常に困難です。

このようなパフォーマンスの問題を回避するために、より優れたストレージ エンジンを備えたデータベースが発明されました。

オープン ソース データベースで CSV エンジンがどのように設計されているかを確認する必要があるかもしれません。あなたの質問に対する(非常に複雑な)答えが見つかるはずです:多くの大きなcsvファイルを処理する最良の方法は何ですか。

于 2012-11-30T23:12:51.623 に答える
0

一度に 1 行ではなく、ブロック単位でファイルを読み取ろうとすることができます。ブロック読み取りは、行ごとの読み取りよりもはるかに高速です。すべてを記憶に読み取ることができれば、素晴らしいことです。そうでない場合は、大きなブロックを読み取り、処理して次に進みます。

于 2012-11-30T22:48:56.340 に答える
0

すべてのファイルをいくつかの配列に読み込み、直接 IO ではなく、変数/配列で作業する必要があると思います。

もちろん、これが可能であれば (数百ではなく少数のファイルしかありません)。

これらのファイルが数百または数千ある場合は、別のデータ ストレージ方法を検討する必要があります。データベースは、このようなことのために設計されています。

もう 1 つのオプションは、CSV ストレージ エンジンを備えた MySQL です。

mysql.com の CSV ストレージ エンジン

ただし、最後にファイル構造を変更する必要がある場合があります。

于 2012-11-30T22:50:42.607 に答える
0

読み取り/書き込み呼び出しの数を減らしてみてください。

  1. getline() の代わりに 2k バイトを 1 回読み取るようにしてください。または、ファイルが大きくない場合は、ファイル全体を一度読み取ることもできます。
  2. バッファリングされた書き込みを使用します。また、書き込みごとにファイルを閉じないでください。ファイル全体の書き込みが終了してから、ファイルを閉じてください。
于 2012-11-30T22:51:27.877 に答える