🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: comp.lang.c.moderated
Article #2649

Re: sscanf behavior (bug in glibc?)

#2649
From: those who know me have no need o...
Date: Fri, 22 Mar 2002 04:11
96 lines
4708 bytes
[fu-t set]
User-Agent: Gnus/5.090006 (Oort Gnus v0.06) XEmacs/21.1 (Cuyahoga Valley,
 i386-redhat-linux)

<clcm-20020321-0024@plethora.net> divulged:

>I was testing performance of sscanf vs fscanf and I found that the
>behavior of sscanf is quite strange (gcc 2.95.2 i386). 

given that only the gnu c compiler and library were tested by you the post
should have gone to a group that concentrates on those items.

>It seems that sscanf always parse the entire string, even if all arguments
>specified in the format are already converted. 

>The small program below shows the problem:

i modified your test program to display the length of each string in the
buffer (in the argc!=3 case) and the length of the buffer overall (in the
!(argc!=3) case), which i've included below, feeling that this made the
attribute actually being tested clearer, i.e., 10,000 sscanf's of a 5 char
string each containing "3.14 " versus scanning a 50,000 character string
containing 10,000 repetitions of "3.14 ", and while i obtained different
results they are comparable so i've not quoted your results.

| $ ./sscanf_test 10000
| sum = 10000, strlen = 5, time = 0.03s
| $ ./sscanf_test 10000 yes
| sum = 10000, strlen = 50000, time = 0.84s

>The results above show that considering PI with its trailing zero stops
>sscanf immediately after the conversion and we get a reasonable time. If
>we do not consider the trailing zero, sscanf stops after having read the
>entire string and the time becomes not acceptable.
>
>The C99 norm doesn't say anything about this strange behavior, so I
>conclude to a bug in the glibc...

glibc uses `memory based files' to deal with buffers as if they were files,
so that the scanf family uses a common specifier scan routine, which calls
fgetc to obtain the next character to consider and ungetc to put it back
onto the `stream' if it's outside the domain of the specifier.  this in
conjunction with leading space elimination appears to have significant
overhead.

testing this on a different type of system, e.g., tru64 unix 5.1a on a
ds-10l w/466mhz ev6 cpu using the compaq supplied c compiler and library
produces ...

| $ ./sscanf_test 10000
| sum = 10000, strlen = 5, time = 0.016666s
| $ ./sscanf_test 10000 yes
| sum = 10000, strlen = 50000, time = 0.116662s

slightly modified version of original program [bug calculating max_item
corrected and display strlen(str) instead of `long string = yes/no']:

| #include <stdio.h>
| #include <stdlib.h>
| #include <string.h>
| #include <time.h>
| 
| #define PI "3.14 "
| #define CHRONO (((double)t1-t0)/CLOCKS_PER_SEC)
| 
| int
| main(int argc, char *argv[])
| {
|   size_t const max_item = strtoul(argc >= 2 ? argv[1] : "10000", NULL, 0);
|   size_t const item_size = strlen(PI) + (argc != 3);
|   size_t const max_size = max_item * item_size;
|   char str[max_size + 1];
|   clock_t t0, t1;
|   size_t sum = 0;
|   size_t i;
|   float pi;
|   
|   for(i=0; i<max_size; i += item_size)
|     memcpy(str+i, PI, item_size);
|   str[max_size] = 0;
| 
|   t0 = clock();
|   for(i=0; i<max_size; i += item_size)
|     sum += sscanf(str+i, "%f", &pi);
|   t1 = clock();
| 
|   printf("sum = %u, strlen = %u, time = %gs\n",
|          sum, strlen(str), CHRONO);
|   
|   return 0;
| }

-- 
bringing you boring signatures for 17 years
-- 
comp.lang.c.moderated - moderation address: clcm@plethora.net
Technical Details
Message-ID: <clcm-20020321-0039@plethora.net>
Path: arc1-ca.pugleaf.net!archiver1.google.com!news1.google.com!newsfeed.stanford.edu!logbridge.uoregon.edu!newspeer.monmouth.com!priapus.visi.com!news-out.visi.com!hermes.visi.com!gemini.plethora.net.POSTED!not-for-mail
References: <clcm-20020321-0024@plethora.net>

Show Full Headers
Complete Article Headers
X-Google-Language: ENGLISH,ASCII-7-bit
X-Google-Thread: 1014db,48f3a7459de71079
X-Google-Attributes: gid1014db,public
X-Google-Thread: 100850,48f3a7459de71079
X-Google-Attributes: gid100850,public
X-Google-Thread: 113d02,15bc8c75a9c9efc4,start
X-Google-Attributes: gid113d02,public
X-Google-ArrivalTime: 2002-03-21 20:11:54 PST
Path: arc1-ca.pugleaf.net!archiver1.google.com!news1.google.com!newsfeed.stanford.edu!logbridge.uoregon.edu!newspeer.monmouth.com!priapus.visi.com!news-out.visi.com!hermes.visi.com!gemini.plethora.net.POSTED!not-for-mail
Subject: Re: sscanf behavior (bug in glibc?)
Approved: clc@plethora.net
References: <clcm-20020321-0024@plethora.net>
From: those who know me have no need of my name <not-a-real-address@usa.net>
Organization: earthfriends
Followup-To: gnu.gcc.bug
Return-Path: <news@lana.pathlink.com>
Content-Type: text/plain; charset=us-ascii
Mime-Version: 1.0
Newsgroups: comp.lang.c.moderated,comp.lang.c,gnu.gcc.bug
Message-ID: <clcm-20020321-0039@plethora.net>
Originator: clcm@plethora.net (Comp Lang C'Moderated)
Date: 22 Mar 2002 04:11:53 GMT
Lines: 96
NNTP-Posting-Host: 8e42f89a.news.plethora.net
X-Trace: 1016770313 gemini.plethora.net 79559 clcm@205.166.146.1
X-Complaints-To: abuse@plethora.net