Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Fastest way to read numerical values from text file in C++ (double in this case)

Tags:

c++

Currently, my code is simply this:

void ReadFile(double Cst[][1000], char* FileName, int height)

FILE* ifp;
double value;
int nRead = 0;
int mRead = 0;

//open the file, check if successful
ifp = fopen( FileName, "r" );
if (ifp==NULL){
    ...
}


for (nRead = 0; nRead < height; nRead++){
    for (mRead = 0; mRead < 1000; mRead++){
        fscanf(ifp, "%le",&value);
        Cst[nRead][mRead]=value;
    }
}

fclose(ifp);

What can I change to make it the fastest possible?

like image 481
Simon Avatar asked Apr 15 '11 15:04

Simon


People also ask

What is the fastest way to read a file in C?

read() posted the fastest time overall, fread() posted really consistent times. This may have been to some small hiccup during the testing, however.


1 Answers

Boost.Spirit.QI comes with a benchmark that compares the performance of std::atof, std::strtod, and boost::spirit::qi::double_. Here are the results on my system, using VC++ 2010 SP1 x64 and Boost 1.46.1:

atof_test: 4.1579 seconds
strtod_test: 4.2339 seconds
spirit_qi_double_test: 1.2822 seconds

This puts Spirit.QI at 230% faster than the next fastest verifiable* option and 224% faster than the next fastest unverifiable option – pretty fast, I'd say!

* Unlike std::atof, std::strtod and Boost.Spirit will let you know whether or not the input was valid.


Update: I've rerun the benchmark, additionally using Boost.Spirit.X3's boost::spirit::x3::double_; here are the results on my present system, using VC++ 2015 Update 3 x64 and Boost 1.61.0:

atof_test: 2.2874 seconds
strtod_test: 2.2923 seconds
spirit_qi_double_test: 0.4849 seconds
spirit_x3_double_test: 0.4308 seconds

This puts Spirit.QI at 373% faster than the next fastest verifiable option and 372% faster than the next fastest unverifiable option, and Spirit.X3 at 432% faster than the next fastest verifiable option and 431% faster than the next fastest unverifiable option – things have improved significantly for Spirit, and on top of that, the X3-based code compiles in about &frac15; of the time as the QI-based code, so wins all around there as well!

Additionally, I've benchmarked the code in @Potatoswatter's answer (modified with double-precision exponent table and support for negative numbers (code)), @6502's answer, and @Mehrdad's answer, with the same build and test environment. Here are the results (@6502's code excluded as half of my sample inputs use scientific notation, which his code does not support):

potatoswatter_test: 0.2358 seconds
mehrdad_test: 0.3415 seconds

If all inputs are converted to fixed notation, we can test @6502's code as well:

atof_test: 3.6249 seconds
strtod_test: 3.7023 seconds
spirit_qi_double_test: 1.0763 seconds
spirit_x3_double_test: 2.3657 seconds
potatoswatter_test: 0.8347 seconds
6502_test: 4.1463 seconds
mehrdad_test: 1.3471 seconds

One note of interest is that QI fails to parse some very long fixed-notation inputs; X3 parses these correctly, but runs significantly slower than with short scientific-notation inputs.

like image 188
ildjarn Avatar answered Sep 27 '22 20:09

ildjarn