logo       

Re: fscanf performance > 10x slower in 2.1.69 compared to 2.1.50 on Windows: msg#00011

gnu.octave.bugs

Subject: Re: fscanf performance > 10x slower in 2.1.69 compared to 2.1.50 on Windows

I did some investigating as to the source of this problem, and have determined that the stream inserter for floating point numbers is quite slow. This accounts for about 2/3s of the time. About 10% of the time is spent extracting and replacing characters to handle NA, Nan, and Inf entries.

The following code is about 3x faster (slower than before, but perhaps acceptable). It replaces the "octave_scan" template specialization for double* in oct-stream.cc.

#define TMP_FP_BUFSIZE 128
template <>
std::istream&
octave_scan (std::istream& is, const scanf_format_elt& fmt, double* valptr)
{
double& ref = *valptr;

char buf[TMP_FP_BUFSIZE];
switch (fmt.type)
{
case 'e':
case 'f':
case 'g':
{
is.width(TMP_FP_BUFSIZE-1); // Protect image against strange file
buf[TMP_FP_BUFSIZE-2] = 0; // Zero char sentinel
is >> buf;
if (is && buf[TMP_FP_BUFSIZE-2]==0) // Not eof, and field wasn't gigantic
{
if (isdigit(buf[0]) || buf[0]=='+' || buf[0] == '-' || buf[0]=='.')
{
ref = atof(buf);
}
else if (strcmp(buf, "NA")==0)
{
ref = octave_NA;
}
else if (strcmp(buf, "NaN")==0)
{
ref = octave_NaN;
}
else if (strcmp(buf, "Inf") == 0)
{
ref = octave_Inf;
}
else {
is.setstate(std::ios_base::failbit);
}
}
else { // Unparsable number (too long). Set fail and quit
if (buf[TMP_FP_BUFSIZE-2]==0) is.setstate(std::ios_base::failbit);
}
break;
}
default:
panic_impossible ();
break;
}
return is;
}


-------------------------------------------------------------
Octave is freely available under the terms of the GNU GPL.

Octave's home on the web: http://www.octave.org
How to fund new projects: http://www.octave.org/funding.html
Subscription information: http://www.octave.org/archive.html
-------------------------------------------------------------




<Prev in Thread] Current Thread [Next in Thread>
Google Custom Search

News | FAQ | advertise