|
From: Robert H. <en...@no...> - 2005-06-09 23:16:28
|
On Thu, 9 Jun 2005, Ethan Merritt wrote: > Not the factor of 10X that Dimitrios Apostolou was hoping for, > but up to a factor of 5X depending on the platform. My measurements using gnuplot on a 2000x2000 array, do seem to be closer to the 10x. I'm assuming the simple test case is much more efficient in cache usage, and so see less of an improvement. Rob |
|
From:
<br...@ph...> - 2005-06-10 04:16:55
|
Robert Hart wrote: > My measurements using gnuplot on a 2000x2000 array, do seem to be closer > to the 10x. I'm assuming the simple test case is much more efficient in > cache usage, and so see less of an improvement. There's no way cache effects can explain a change of speed difference between two library functions executed in a tight loop. |
|
From: Ethan M. <merritt@u.washington.edu> - 2005-06-09 20:54:58
|
On Thursday 09 June 2005 09:12 am, Robert Hart wrote:
> On Thu, 2005-06-09 at 21:18 +0800, Hans-Bernhard Br=C3=B6ker wrote:
> >=20
> > Well, here's an ancient comment right taken directly from datafile.c:
> >=20
> > /* cannot trust strtod - eg strtod("-",&p) */
I cannot make any sense of that comment either. ANSI says, in regard
to scanf with %f
"The format of the token should be that expected by the function
strtod for a floating-point number that uses decimal notation".
So there doesn't seem to be much room for scanf and strtod to parse
numbers differently.
=2D-=20
Ethan A Merritt merritt@u.washington.edu
Biomolecular Structure Center
Mailstop 357742
University of Washington, Seattle, WA 98195
|
|
From: Daniel J S. <dan...@ie...> - 2005-06-09 21:11:45
|
Ethan Merritt wrote:
> On Thursday 09 June 2005 09:12 am, Robert Hart wrote:
>=20
>>On Thu, 2005-06-09 at 21:18 +0800, Hans-Bernhard Br=C3=B6ker wrote:
>>
>>>Well, here's an ancient comment right taken directly from datafile.c:
>>>
>>> /* cannot trust strtod - eg strtod("-",&p) */
>=20
>=20
> I cannot make any sense of that comment either. ANSI says, in regard
> to scanf with %f
> "The format of the token should be that expected by the function
> strtod for a floating-point number that uses decimal notation".
> So there doesn't seem to be much room for scanf and strtod to parse
> numbers differently.
Perhaps this was mentioned, but a conjecture on the slowness of scanf() m=
ight be=20
that the number of output arguments is unknown and requires special handl=
ing,=20
whereas strtod() has only one output argument.
Dan
|
|
From:
<br...@ph...> - 2005-06-10 02:42:42
|
Robert Hart wrote:
> On Thu, 2005-06-09 at 21:18 +0800, Hans-Bernhard Bröker wrote:
>>Robert Hart wrote:
>>>strtod() is indeed significantly faster than sscanf.
>>And I still don't see why that should be the case...
> sscanf takes an arbitrary format string as an argument, which it must
> parse every time it is called, it is also very generic so, I imagine,
> ends up doing a lot of extra work to support this.
None of that extra work can possibly be "a lot", compared to the heavy
task of actually doing a floating-point conversion. I've inspected libc
source sufficiently to be reasonably sure of that. There's no way the
format string parser in sscanf() can take 10 times as much time as the
actual floating point parsing (which may very well be done by calling
strtod(), internally).
>> /* cannot trust strtod - eg strtod("-",&p) */
> I've seen this comment, and tried it out. In my tests this isn't an
> issue. The man page says:
>
> If no conversion is performed, zero is returned and the value of nptr
> is stored in the location referenced by endptr.
That's the manpage of one system. "To trust" means we must be sure that
all implementations on the planet get this right. Are we?
> I have attached my test program. I can't find any input on my system
> that gives different results between sscanf and strtod.
"On my system" being the key phrase here, which means that the test is
inconclusive.
> Well comments in the code say "%n" doesn't work on OSK. I don't even
> know what OSK is,
It's actually called OS-9, a realtime OS for 68000 processors IIRC.
> but if strtod works where sscanf doesn't then that's a win.
IF. But we don't know that.
|
|
From: Ethan M. <merritt@u.washington.edu> - 2005-06-10 04:38:23
|
On Thursday 09 June 2005 07:44 pm, Hans-Bernhard Br=F6ker wrote: > > It's actually called OS-9, a realtime OS for 68000 processors IIRC. > > but if strtod works where sscanf doesn't then that's a win. > > IF. But we don't know that. A bit of poking around on the web leads me to the conclusion that there is no single libc for OS9/OSK. There are many, including (since 1994) gcc and glibc. Trying to figure out which of these long ago libc variants was having a problem with %n is probably a lost cause. To the extent we can assume anything, I think we can assume that a glibc implemtation provides strtod and follows the ANSI requirement that strtod and scanf use the same format rules. This is beating a dead horse, though. The whole point of OSK is that it runs in minimal RAM on embedded systems on old hardware. I don't believe for a minute that anyone is going to install a full-blown gnuplot version 4.2 on one of these old devices. I suggest that we concentrate on the more relevant point of whether a 2X or 5X or 10X or whatever speed-up is worth the slight uncertainty of replacing the current scanf() call with strtod(). ANSI says they behave the same on formatting, and benchmarking shows that strtod() is faster. Sounds like a win to me. =20 The strongest counter-argument I see is that if you really want to read in these huge matrices, you're better off using the binary input mode anyhow. Or if binary mode is not faster, then we should be fixing that first. =2D-=20 Ethan A Merritt Biomolecular Structure Center University of Washington 98195-7742 |
|
From: Daniel J S. <dan...@ie...> - 2005-06-10 05:17:27
|
Hans-Bernhard Br=F6ker wrote: > Robert Hart wrote: >=20 >> On Thu, 2005-06-09 at 21:18 +0800, Hans-Bernhard Br=F6ker wrote: >> >>> Robert Hart wrote: >=20 >=20 >>>> strtod() is indeed significantly faster than sscanf.=20 >=20 >=20 >>> And I still don't see why that should be the case... >=20 >=20 >> sscanf takes an arbitrary format string as an argument, which it must >> parse every time it is called, it is also very generic so, I imagine, >> ends up doing a lot of extra work to support this.=20 >=20 >=20 > None of that extra work can possibly be "a lot", compared to the heavy=20 > task of actually doing a floating-point conversion. I've inspected lib= c=20 > source sufficiently to be reasonably sure of that. There's no way the=20 > format string parser in sscanf() can take 10 times as much time as the=20 > actual floating point parsing (which may very well be done by calling=20 > strtod(), internally). I think I've found a discussion that parallels what has been here: http://dbforums.com/t327787.html See if you agree. For example: "So this is a quality-of-implementation issue, at most, and it's not rest= ricted to glibc. I've just found O(n^2) on another platform with a different libc, = too. BTW: if I change the call from sscanf() to strtod(), the run time becomes= O(n)=20 in all platforms I cared to test. I.e. the difference must happen in sscanf() it= self,=20 and be caused by the length of the remainder of the input string following the m= atched=20 3.14." Now, here's the interesting part. :) The date of this contribution is M= ay 22,=20 2002. And the contributor of this was... Hans-Bernhard Broeker (br...@ph...) :) |
|
From: Hans-Bernhard B. <br...@ph...> - 2005-06-11 11:56:42
|
Daniel J Sebald wrote:
> Hans-Bernhard Br=F6ker wrote:
>> Robert Hart wrote:
>>> sscanf takes an arbitrary format string as an argument, which it must=
>>> parse every time it is called, it is also very generic so, I imagine,=
>>> ends up doing a lot of extra work to support this.=20
>> None of that extra work can possibly be "a lot", compared to the heavy=
=20
>> task of actually doing a floating-point conversion. =20
[... Dan found a quote from myself...:]
> BTW: if I change the call from sscanf() to strtod(), the run time=20
> becomes O(n) in all platforms I cared to test.=20
Well, the processing that caused that example to be O(N^2) wasn't=20
related to the format string at all --- it was triggered by handling of=20
input string. So my answer to Robert quoted above still holds.
Apparently the culprit implementations in that case (glibc, DJGPP,=20
possibly others) run strlen() on the input string as part of the job of=20
constructing a memory-based pseudo-file, so they can essentially=20
implement sscanf() on top of fscanf(). That's really quite a stupid way =
of doing this.
But yes, indeed, a QoI issue like this could explain the speed=20
difference we're seeing here. The enormous length of the OP's matrix=20
datafile's lines would trigger this copying overhead on platforms=20
working that way. The crucial difference in that case turned out the=20
length of the "tail" after the scanned number, e.g.
sscanf("3.14 ", "%lf", &mydouble);
would complete much faster than
sscanf("3.14 [10000 other characters here...]", "%lf", &mydouble);
> Now, here's the interesting part. :) The date of this contribution is=
=20
> May 22, 2002. And the contributor of this was... Hans-Bernhard Broeker=
=20
> :)
Let's just say I know full well why I never claim to have perfect memory =
;-)
|
|
From: Ethan M. <merritt@u.washington.edu> - 2005-06-09 21:13:16
Attachments:
scan_data_9jun2005.patch
|
On Thursday 09 June 2005 04:14 am, Robert Hart wrote: > > #ifdef USE_STRTOD > char *fin; > df_column[df_no_cols].datum=strtod(s,&fin); > used=s-fin; > count=used?1:0; > #else > count = sscanf(s, "%lf%n", &df_column[df_no_cols].datum, &used); > #endif Somewhat more complete patch attached, adding a TBOOLEAN to toggle fortran_float handling. I've run it through the usual test suite, but haven't yet tried deliberately to break it with oddball input data. -- Ethan A Merritt merritt@u.washington.edu Biomolecular Structure Center Mailstop 357742 University of Washington, Seattle, WA 98195 |
|
From: Robert H. <en...@no...> - 2005-06-09 23:11:05
|
On Thu, 9 Jun 2005, Ethan Merritt wrote: > Somewhat more complete patch attached, adding a TBOOLEAN to > toggle fortran_float handling. You didn't change the sscanf for the rereading after changing dDqQ. It would be better to be consistent. There might even be somebody trying to read a huge matrix of fortran floats into gnuplot. |