기본 OS가 fprintf()를 처리하는 방식에 따라 fwrite()에서 효율성을 얻을 수 있습니다.
앞서 언급 한 것처럼 fwrite()를 직접 수행 할 수는 없지만 sprintf()를 사용하여 csv 텍스트의 서식을 지정한 다음 큰 버퍼로 밀어 넣을 수 있습니다. 버퍼가 가득 차면 전체 버퍼를 fwrite()합니다.
운영 체제 내에서 파일 I/O를 구현하면 이미이 작업이 수행되기 때문에 fprint()가 fprintf()보다 더 효율적이지 않을 수 있습니다.
에릭의 답변에서 언급했듯이이 데이터를 저장하는 가장 효율적인 방법은 직접 바이너리 형식을 사용하는 것입니다. 예를 들어, 데이터를 완전 부동 소수점 정밀도가 필요합니까? 예를 들어, 데이터를 완전 부동 소수점 정밀도가 필요합니까? 보고하는 계산을위한 적절한 정밀도를 유지하면서 16 비트 고정 소수점 int로 변환하고 32 비트 부호없는 int 당 두 개의 데이터 포인트를 저장할 수 있습니까? 부호있는 int 집합으로 취급하면 16 비트 부호있는 int 값은 5 자리 정밀도가됩니다.
이 데이터에 대해 추가 처리를 수행하는 경우 처리 시간이 제어 할 수 없으므로 Excel 또는 Matlab을 사용하지 않으려 고합니다. C 또는 C++로 처리 알고리즘을 개발하면 이진 데이터 형식이 문제가되지 않습니다.
이 데이터를 그래프로 표시하는 경우 그래픽 디스플레이는 데이터를 기본적으로 다운 샘플링합니다. 따라서 10k 포인트와 비슷한 것으로 처리하고 플롯에 의미있는 출력 통계를 출력 할 수 있습니다.
어쨌든, 내 아이디어가 있습니다. 아마 당신이 이미 문제를 풀었 기 때문에 좀 더 일반적인 의미로 작성되었으므로 아마도 비슷한 질문을 한 다른 사람들이 읽게 될 것입니다.
편집 : 여기
// what's faster, fwrite or fprintf?
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#define HUGE_NUMBER 1000
LARGE_INTEGER ticksPerSecond;
LARGE_INTEGER time1;
LARGE_INTEGER time2;
float floatDiffTime;
const int runs = 1000000;
int main(int argc, char* argv[])
{
// Get the speed of the CPU
QueryPerformanceFrequency(&ticksPerSecond);
printf("Your computer does %lld ticks per second\n", ticksPerSecond.QuadPart);
// %lld means type "long long" int, which is the
// 64 bit int which is what we want here.
// define some random valued variables to use
// in the print statements
int a = 5;
double b = 9.2919e92;
char c = 'x';
char * d = "blah blah blah";
// test start: open a file to write
FILE *outfile = fopen("testfile.txt", "w");
char buf[HUGE_NUMBER];
int i;
int index = 0;
//Test line-by-line fprintf
// START timing
QueryPerformanceCounter(&time1);
memset(buf,'\0', HUGE_NUMBER);
for(i=0; i<runs; i++)
{
fprintf(outfile, "blah %i %f %c %s\n", a, b, c, d);
}
fflush (outfile);
fclose(outfile);
// STOP timing
QueryPerformanceCounter(&time2);
// get the difference between time1 and time2,
// and that is how long the for loop took to run.
floatDiffTime = ((float)time2.QuadPart - time1.QuadPart)/ticksPerSecond.QuadPart;
printf("line-by-line fprintf took %f seconds\n", floatDiffTime);
//Test fprintf
// START timing
QueryPerformanceCounter(&time1);
memset(buf,'\0', HUGE_NUMBER);
for(i=0; i<runs; i++)
{
sprintf(&buf[index], "blah %i %f %c %s\n", a, b, c, d);
index += strlen(&buf[index]);
if(index >= HUGE_NUMBER) {
fprintf(outfile, "%s", buf);
index = 0;
memset(buf,'\0', HUGE_NUMBER);
}
}
fflush (outfile);
fclose(outfile);
// STOP timing
QueryPerformanceCounter(&time2);
// get the difference between time1 and time2,
// and that is how long the for loop took to run.
floatDiffTime = ((float)time2.QuadPart - time1.QuadPart)/ticksPerSecond.QuadPart;
printf("fprintf took %f seconds\n", floatDiffTime);
//Test fwrite
outfile = fopen("testfile.txt", "w");
index = 0;
/////////////////////
// START timing
QueryPerformanceCounter(&time1);
memset(buf,'\0', HUGE_NUMBER);
for(i=0; i<runs; i++)
{
sprintf(&buf[index], "blah %i %f %c %s\n", a, b, c, d);
index += strlen(&buf[index]);
if(index >= HUGE_NUMBER) {
fwrite(buf, 1, strlen(buf), outfile);
index = 0;
//printf("buf size: %d\n", strlen(buf));
memset(buf,'\0', HUGE_NUMBER);
}
}
fflush(outfile);
fclose(outfile);
////////////////////
// STOP timing
QueryPerformanceCounter(&time2);
// get the difference between time1 and time2,
// and that is how long the for loop took to run.
floatDiffTime = ((float)time2.QuadPart - time1.QuadPart)/ticksPerSecond.QuadPart;
printf("fwrite took %f seconds\n", floatDiffTime);
//Test WriteFile
outfile = fopen("testfile.txt", "w");
index = 0;
DWORD bWritten = 0;
/////////////////////
// START timing
QueryPerformanceCounter(&time1);
memset(buf,'\0', HUGE_NUMBER);
for(i=0; i<runs; i++)
{
sprintf(&buf[index], "blah %i %f %c %s\n", a, b, c, d);
index += strlen(&buf[index]);
if(index >= HUGE_NUMBER) {
WriteFile(outfile, buf, strlen(buf), &bWritten, NULL);
index = 0;
//printf("buf size: %d\n", strlen(buf));
memset(buf,'\0', HUGE_NUMBER);
}
}
fflush(outfile);
fclose(outfile);
////////////////////
// STOP timing
QueryPerformanceCounter(&time2);
// get the difference between time1 and time2,
// and that is how long the for loop took to run.
floatDiffTime = ((float)time2.QuadPart - time1.QuadPart)/ticksPerSecond.QuadPart;
printf("WriteFile took %f seconds\n", floatDiffTime);
//Test WriteFile
outfile = fopen("testfile.txt", "w");
index = 0;
bWritten = 0;
/////////////////////
// START timing
QueryPerformanceCounter(&time1);
memset(buf,'\0', HUGE_NUMBER);
for(i=0; i<runs; i++)
{
sprintf(&buf[index], "blah %i %f %c %s\n", a, b, c, d);
WriteFile(outfile, buf, strlen(buf), &bWritten, NULL);
memset(buf,'\0', strlen(buf));
}
fflush(outfile);
fclose(outfile);
////////////////////
// STOP timing
QueryPerformanceCounter(&time2);
// get the difference between time1 and time2,
// and that is how long the for loop took to run.
floatDiffTime = ((float)time2.QuadPart - time1.QuadPart)/ticksPerSecond.QuadPart;
printf("WriteFile line-by-line took %f seconds\n", floatDiffTime);
return 0;
}
그리고 결과 아래 내가 달릴 흥미 검사, 완전한 컴파일 가능한 소스는 ???
Your computer does 2337929 ticks per second
line-by-line fprintf took 2.970491 seconds
fprintf took 2.345687 seconds
fwrite took 3.456101 seconds
WriteFile took 2.131118 seconds
WriteFile line-by-line took 2.495092 seconds
그런 다음 fprintf와로 발송 문자열로 많은 양의 데이터를 버퍼링과 같다() (휴대용) 또는 Windows의 WriteFile() 호출이 처리하는 가장 효율적인 방법이 있습니다 (사용하여 Windows 경우).
컴파일러 명령 :
gcc write_speed_test.c -o wspt
컴파일러 버전 :
$ gcc -v
Using built-in specs.
Target: i686-w64-mingw32
Configured with: ../gcc44-svn/configure --target=i686-w64-mingw32 --host=i686-w64-mingw32 --disable-multilib --disable-nls --disable-win32-registry --prefix=/mingw32 --with-gmp=/mingw32 --with-mpfr=/mingw32 --enable-languages=c,c++
Thread model: win32
gcc version 4.4.3 (GCC)
가 howmuch 데이터는 작성해야합니까? – kangshiyin
격자의 크기에 따라 중첩 for 루프의 부동 소수점 값이 60,000에서 250,000 사이에 있습니다. – user1968603