On Mon, Jun 11, 2012 at 07:14:56AM -0600, Eric Blake wrote: > On 06/11/2012 06:54 AM, Rich Felker wrote: > > >> GNU M4 (at least the master branch, although it has not yet been > >> released as m4 2.0) _wants_ to use freadahead, because it provides at > >> least a 10% speedup in operation. It _really is_ more efficient to peek > >> at the current buffer in one function call than it is to call multiple > >> fgetc_unlocked(), in order to rapidly search for the next character of > >> interest. > > Actually, m4 uses freadptr(), not freadahead(), and _does_ fall back to
OK that makes a lot more sense. But if your goal is to read up until the next character in a particular set of special characters, why not fscanf(f, "%100[^xyz]", ...) with 100 replaced by your buffer size and xyz replaced by the specials? If fscanf is too slow, it seems like this is a QOI bug in fscanf (I'll admit mine is too slow here), but it seems like the right way to do this operation in a way that _can_ be fast if the underlying library handles it well. > > Can you explain how knowing the _number_ of buffered characters helps > > you find the next character of interest efficiently? > > It doesn't. Rather, the speedup comes from the ability to peek into > that buffer in advance, using freadptr(), so that you can use strchr(), > strstr(), or other search functions on the buffer, followed by an > fread() of the appropriate size, all in order to minimize the number of > function calls without reading past the ISO C99 1-byte ungetc() BTW if you're going to propose something to POSIX, I think a variant of getdelim with a scanset rather than a single delimiter character might be a cleaner proposal.. Note that it could be implemented in terms of fscanf and %m[...] on systems that don't have it but which already conform to POSIX 2008. > > As for musl, would adding __freadahead be sufficient to make it use > > __freadahead, or does gnulib hard-code knowledge about which systems > > have which stdio extension functions? > > Depending on the function name you choose, we would have to add an m4 > check to see if __freadahead() is defined; but once we know the name of > the function to check for at configure time, then it is quite simple to > code up gnulib's freadahead.c to call into the internal __freadahead() > function of libc, when one exists. So right now, for DragonFly, it's just hard-coded? If you're willing to put in a test for it, I'm willing to add the function. Rich