bladepit
bladepit

Reputation: 873

fputs vs. fprintf and double

I need to put out a double value into an file. So for all my other string i have to put out i use fputs because i think and timed it that fputs is faster then fprintf.

But if i want to put out the double value i can't do this with fputs so i tried fprintf. This is very slow. I need more time if i replace the fprintf and puts there an fputs("TEST",file);

How can i put out the double as fast as the string. Need i to convert it first to string?

I found some conversion. But if i use them i am as slow as if i use the fprintf.

So how can i put out the double to a file so fast as if i put out a string to the file?

  fputs("TEST",fileout); //FAST
  fprintf(fileout, "%f",p); //SLOW

EDIT:

Times with fprintf double:

END.PROCESSING.DATA: 2013-04-26 08:10:33.000
END.CALC.IN.FILE: 2013-04-26 08:11:13.000

Times with fputs strings:

END.PROCESSING.DATA: 2013-04-26 08:14:10.000
END.CALC.IN.FILE: 2013-04-26 08:14:37.000

The code for that times:

now = time (0);
strftime (buff, 100, "%Y-%m-%d %H:%M:%S.000", localtime (&now));
printf ("END.PROCESSING.DATA: %s\n", buff);

//output file
FILE *fileout;
fileout = fopen("out.txt","w");
double p;
for(i=0; i<17000;i++){
  for(j=0; j<i;j++){
    for(z=0;z<400;z++){
      //DO SOME WORK
    }
    p = 1.0;
    fputs(allsubsts[i],fileout);
    fputs(";",fileout);
    fputs(allsubsts[j],fileout);
    fputs(";",fileout);
    //fprintf(fileout, "%.21g", p);
    fputs("TEST",fileout);
    fputs(";\n",fileout);
  }
}
fclose(fileout);

now = time(0);
strftime(buff,100,"%Y-%m-%d %H:%M:%S.000", localtime(&now));
printf("END.CALC.IN.FILE: %s\n",buff);

Changes between the time are only the change that i put the double instead the TEST string in the file.

Upvotes: 2

Views: 3888

Answers (2)

vitaut
vitaut

Reputation: 55725

In C you can use the ryu library to speed up floating-point output by first formatting the number into a buffer and then writing it out. It is not the fastest method but still better than common printf implementations.

double n = 0.42;
char buf[32];
d2s_buffered(n, buf);
fputs(buf, file);

Using hexadecimal printf format (%a) is an option too but the result may not be as easy to interpret by humans.

In case you can use C++, the same can be achieved with C++17 std::to_char or C++20 std::format without extra dependencies. These methods don't depend on locale and normally use faster algorithms for converting binary floating point into the decimal representation.

Upvotes: 0

R.. GitHub STOP HELPING ICE
R.. GitHub STOP HELPING ICE

Reputation: 215597

Converting a floating point number to a decimal representation is a fundamentally slow operation. You might try using the %a specifier instead of %f to store it as a hex float; this should be much faster and would safely preserve the original value rather than a poor approximation. If you need decimal, you should be using %.21g or similar, not %f, as the latter will lose most of the precision.

If none of this is fast enough for you, then you probably need to save the binary representation of the value directly.

Upvotes: 5

Related Questions