Rocksolid Light

Welcome to novaBBS (click a section below)

mail  files  register  newsreader  groups  login

Message-ID:  

<< WAIT >>


devel / comp.lang.c / Re: Why does C allow structs to have a tag?

SubjectAuthor
* Why does C allow structs to have a tag?James Harris
+* Re: Why does C allow structs to have a tag?David Brown
|`* Re: Why does C allow structs to have a tag?Thiago Adams
| `- Re: Why does C allow structs to have a tag?David Brown
+- Re: Why does C allow structs to have a tag?Öö Tiib
+* Re: Why does C allow structs to have a tag?Bart
|+* Re: Why does C allow structs to have a tag?Kaz Kylheku
||+- Re: Why does C allow structs to have a tag?Bart
||`* Re: Why does C allow structs to have a tag?Manfred
|| `* Re: Why does C allow structs to have a tag?David Brown
||  `* Re: Why does C allow structs to have a tag?Bart
||   +- Re: Why does C allow structs to have a tag?Richard Harnden
||   +* Re: Why does C allow structs to have a tag?Keith Thompson
||   |+* Re: Why does C allow structs to have a tag?Bart
||   ||+- Re: Why does C allow structs to have a tag?Keith Thompson
||   ||`* Re: Why does C allow structs to have a tag?James Harris
||   || `- Re: Why does C allow structs to have a tag?Bart
||   |`* Re: Why does C allow structs to have a tag?Manfred
||   | `* Re: Why does C allow structs to have a tag?Keith Thompson
||   |  `* Re: Why does C allow structs to have a tag?Bart
||   |   +* Re: Why does C allow structs to have a tag?David Brown
||   |   |`- Re: Why does C allow structs to have a tag?Bart
||   |   `* Re: Why does C allow structs to have a tag?Keith Thompson
||   |    `- Re: Why does C allow structs to have a tag?Malcolm McLean
||   `* Re: Why does C allow structs to have a tag?David Brown
||    `* Re: Why does C allow structs to have a tag?Bart
||     +* Re: Why does C allow structs to have a tag?David Brown
||     |`* Re: Why does C allow structs to have a tag?Bart
||     | `* Re: Why does C allow structs to have a tag?Malcolm McLean
||     |  `* Re: Why does C allow structs to have a tag?Bart
||     |   `* Re: Why does C allow structs to have a tag?Kaz Kylheku
||     |    `* Re: Why does C allow structs to have a tag?Bart
||     |     +- Re: Why does C allow structs to have a tag?James Harris
||     |     `* Re: Why does C allow structs to have a tag?Kaz Kylheku
||     |      `* Re: Why does C allow structs to have a tag?Bart
||     |       `* Re: Why does C allow structs to have a tag?Keith Thompson
||     |        `* Re: Why does C allow structs to have a tag?Bart
||     |         `- Re: Why does C allow structs to have a tag?Keith Thompson
||     `* Re: Why does C allow structs to have a tag?James Harris
||      `- Re: Why does C allow structs to have a tag?Bart
|`- Re: Why does C allow structs to have a tag?Keith Thompson
+* Re: Why does C allow structs to have a tag?Kaz Kylheku
|`* Re: Why does C allow structs to have a tag?Bart
| `- Re: Why does C allow structs to have a tag?James Harris
+- Re: Why does C allow structs to have a tag?James Kuyper
+* Re: Why does C allow structs to have a tag?Richard Damon
|`- Re: Why does C allow structs to have a tag?James Harris
+* Re: Why does C allow structs to have a tag?Joe Pfeiffer
|`* Re: Why does C allow structs to have a tag?Malcolm McLean
| +* Re: Why does C allow structs to have a tag?Guillaume
| |+* Re: Why does C allow structs to have a tag?Kaz Kylheku
| ||`* Re: Why does C allow structs to have a tag?Bart
| || `* Re: Why does C allow structs to have a tag?Kaz Kylheku
| ||  `* Re: Why does C allow structs to have a tag?Bart
| ||   `- Re: Why does C allow structs to have a tag?Keith Thompson
| |`* Re: Why does C allow structs to have a tag?James Kuyper
| | `* Re: Why does C allow structs to have a tag?Bart
| |  `* Re: Why does C allow structs to have a tag?Kaz Kylheku
| |   +* Re: Why does C allow structs to have a tag?Bart
| |   |`* Re: Why does C allow structs to have a tag?Kaz Kylheku
| |   | `* Re: Why does C allow structs to have a tag?Bart
| |   |  `* Re: Why does C allow structs to have a tag?David Brown
| |   |   `* Re: Why does C allow structs to have a tag?Bart
| |   |    +* Re: Why does C allow structs to have a tag?David Brown
| |   |    |`* Re: Why does C allow structs to have a tag?Bart
| |   |    | `* Re: Why does C allow structs to have a tag?David Brown
| |   |    |  +* Re: Why does C allow structs to have a tag?Manfred
| |   |    |  |`- Re: Why does C allow structs to have a tag?David Brown
| |   |    |  +- Re: Why does C allow structs to have a tag?Bart
| |   |    |  `* Re: Why does C allow structs to have a tag?Bart
| |   |    |   +- Re: Why does C allow structs to have a tag?David Brown
| |   |    |   `* Re: Why does C allow structs to have a tag?Keith Thompson
| |   |    |    +* Re: Why does C allow structs to have a tag?Guillaume
| |   |    |    |+* Re: Why does C allow structs to have a tag?Kaz Kylheku
| |   |    |    ||`- Re: Why does C allow structs to have a tag?Keith Thompson
| |   |    |    |+- Re: Why does C allow structs to have a tag?Keith Thompson
| |   |    |    |+- Re: Why does C allow structs to have a tag?Keith Thompson
| |   |    |    |`- Re: Why does C allow structs to have a tag?David Brown
| |   |    |    `* Re: Why does C allow structs to have a tag?Bart
| |   |    |     `* Re: Why does C allow structs to have a tag?Keith Thompson
| |   |    |      `* Re: Why does C allow structs to have a tag?Bart
| |   |    |       +* Re: Why does C allow structs to have a tag?Kaz Kylheku
| |   |    |       |`* Re: Why does C allow structs to have a tag?Ben Bacarisse
| |   |    |       | `* Re: Why does C allow structs to have a tag?Bart
| |   |    |       |  `* Re: Why does C allow structs to have a tag?Kaz Kylheku
| |   |    |       |   `* Re: Why does C allow structs to have a tag?Bart
| |   |    |       |    +* Re: Why does C allow structs to have a tag?Kaz Kylheku
| |   |    |       |    |`* Re: Why does C allow structs to have a tag?Bart
| |   |    |       |    | `- Re: Why does C allow structs to have a tag?Keith Thompson
| |   |    |       |    `- Re: Why does C allow structs to have a tag?Keith Thompson
| |   |    |       `- Re: Why does C allow structs to have a tag?David Brown
| |   |    `* Re: Why does C allow structs to have a tag?Kaz Kylheku
| |   |     `* Re: Why does C allow structs to have a tag?Bart
| |   |      `* Re: Why does C allow structs to have a tag?Kaz Kylheku
| |   |       `- Re: Why does C allow structs to have a tag?Bart
| |   `* Re: Why does C allow structs to have a tag?Bart
| |    +- Re: Why does C allow structs to have a tag?Keith Thompson
| |    `- Re: Why does C allow structs to have a tag?Kaz Kylheku
| +* Re: Why does C allow structs to have a tag?Joe Pfeiffer
| |`- Re: Why does C allow structs to have a tag?Kaz Kylheku
| `- Re: Why does C allow structs to have a tag?Richard Damon
+* Re: Why does C allow structs to have a tag?John Bode
+- Re: Why does C allow structs to have a tag?Siri Cruise
`* Re: Why does C allow structs to have a tag?Andrey Tarasevich

Pages:12345678910111213141516
Re: Why does C allow structs to have a tag?

<8LWQI.11440$fI7.7665@fx33.iad>

  copy mid

https://www.novabbs.com/devel/article-flat.php?id=17918&group=comp.lang.c#17918

  copy link   Newsgroups: comp.lang.c
Path: i2pn2.org!i2pn.org!aioe.org!news.uzoreto.com!news-out.netnews.com!news.alt.net!fdc2.netnews.com!peer03.ams1!peer.ams1.xlned.com!news.xlned.com!peer01.iad!feed-me.highwinds-media.com!news.highwinds-media.com!fx33.iad.POSTED!not-for-mail
Subject: Re: Why does C allow structs to have a tag?
Newsgroups: comp.lang.c
References: <s9iea5$n5c$1@dont-email.me> <WowPI.4743$NQ1.1007@fx48.iad>
<sembba$oul$1@dont-email.me> <CrQPI.669$bS5.239@fx21.iad>
<seoqf4$pj7$1@dont-email.me> <87czqnlp2m.fsf@bsb.me.uk>
<sepbrd$vg4$1@dont-email.me> <877dgvljpf.fsf@bsb.me.uk>
<2a1b4347-595a-469a-8df1-db64af9896acn@googlegroups.com>
<Wg_PI.6656$NQ1.5159@fx48.iad>
<94f47c65-5f5f-44d1-bc37-d51155624ae5n@googlegroups.com>
<sesbbk$63q$1@dont-email.me> <sf10rj$7g9$1@z-news.wcss.wroc.pl>
<sf1712$t4a$1@dont-email.me> <sf1bdc$pa9$1@z-news.wcss.wroc.pl>
From: nos...@dfs.com (DFS)
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:78.0) Gecko/20100101
Thunderbird/78.13.0
MIME-Version: 1.0
In-Reply-To: <sf1bdc$pa9$1@z-news.wcss.wroc.pl>
Content-Type: text/plain; charset=utf-8; format=flowed
Content-Language: en-US
Content-Transfer-Encoding: 7bit
Lines: 15
Message-ID: <8LWQI.11440$fI7.7665@fx33.iad>
X-Complaints-To: abuse@blocknews.net
NNTP-Posting-Date: Wed, 11 Aug 2021 20:51:16 UTC
Organization: blocknews - www.blocknews.net
Date: Wed, 11 Aug 2021 16:51:15 -0400
X-Received-Bytes: 1716
 by: DFS - Wed, 11 Aug 2021 20:51 UTC

On 8/11/2021 4:19 PM, antispam@math.uni.wroc.pl wrote:

> DFS can be excused as he apparently does not know what
> happened.

I didn't know why at first, but Kaz Kylheku explained it: the speed
difference in printf() is due to the implementation used in tcc
(msvcrt.dll) vs that used in mingw gcc.

I tried to find printf() code in the source for gcc 11.1.0, but
couldn't. Do you know how to find it?

Re: Why does C allow structs to have a tag?

<aXWQI.4499$6h1.2228@fx39.iad>

  copy mid

https://www.novabbs.com/devel/article-flat.php?id=17919&group=comp.lang.c#17919

  copy link   Newsgroups: comp.lang.c
Path: i2pn2.org!i2pn.org!aioe.org!feeder1.feed.usenet.farm!feed.usenet.farm!peer02.ams4!peer.am4.highwinds-media.com!peer02.iad!feed-me.highwinds-media.com!news.highwinds-media.com!fx39.iad.POSTED!not-for-mail
From: nos...@dfs.com (DFS)
Subject: Re: Why does C allow structs to have a tag?
Newsgroups: comp.lang.c
References: <s9iea5$n5c$1@dont-email.me> <CjzOI.1030$Bg6.61@fx42.iad>
<seejf8$9ti$1@dont-email.me> <WowPI.4743$NQ1.1007@fx48.iad>
<sembba$oul$1@dont-email.me> <CrQPI.669$bS5.239@fx21.iad>
<seoqf4$pj7$1@dont-email.me> <87czqnlp2m.fsf@bsb.me.uk>
<WFWPI.1865$un2.1665@fx04.iad> <FiCQI.401$uk4.259@fx20.iad>
<poCQI.37363$EF2.25668@fx47.iad> <VNCQI.5685$Ug5.514@fx24.iad>
<seuu75$il3$1@dont-email.me> <TEEQI.5686$Ug5.143@fx24.iad>
<sf021q$78n$1@z-news.wcss.wroc.pl> <9GUQI.8728$Bg6.71@fx42.iad>
<r1VQI.5573$xY.4985@fx05.iad>
X-Mozilla-News-Host: news://usnews.blocknews.net
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:78.0) Gecko/20100101
Thunderbird/78.13.0
MIME-Version: 1.0
In-Reply-To: <r1VQI.5573$xY.4985@fx05.iad>
Content-Type: text/plain; charset=utf-8; format=flowed
Content-Language: en-US
Content-Transfer-Encoding: 7bit
Lines: 90
Message-ID: <aXWQI.4499$6h1.2228@fx39.iad>
X-Complaints-To: abuse@blocknews.net
NNTP-Posting-Date: Wed, 11 Aug 2021 21:04:06 UTC
Organization: blocknews - www.blocknews.net
Date: Wed, 11 Aug 2021 17:04:05 -0400
X-Received-Bytes: 4781
 by: DFS - Wed, 11 Aug 2021 21:04 UTC

On 8/11/2021 2:54 PM, Scott Lurndal wrote:

> I was thinking more along the lines of this:
>
> static char line[12000000];
>
> /**
> * Catenate the words from 'matchwords' into 'line', computing the
> * word length of the longest single word along the way.
> *
> * @param matchwords A vector of character pointers, one for each word
> * @param matchcnt The number of entries in the matchwords vector.
> */
> void
> showresults(char **matchwords, size_t matchcnt)
> {
> size_t longest_word = 0ul;
> char *lp = line;
> char *elp = &line[sizeof(line)];
>
> for(size_t i = 0ul; i < matchcount; i++) {
> char *cp = *matchwords++;
> size_t len = 0ul;
> while ((*cp != '\0') && (lp < elp)) {
> len++;
> *lp++ = *cp++;
> }
> longest_word = max(longest_word, len);
> }
>
> if (lp < elp) *lp++ = '\0';
> else line[sizeof(line)-1] = '\0';
>
> puts(line);
> }
>
> It will silently truncate the output string if 'line'
> isn't large enough to collect all the words in 'matchwords'.
>
> The implementation of max is left to the student.

Well, I'm not a student (in the usual sense) and this isn't homework
(it's just a hobby), but I do appreciate the suggestions and code.

However:

* before constructing the string you have to find the longest word,
which you use to determine how many columns fit in the current width
of the terminal. Each word takes up the same horizontal space:
longest word + 2 blanks

* the output of your code is one long string, with no spaces between the
words and no newlines after every N columns

Substring to search for: catt
backscatterbackscatteredbackscatteringbackscattersbescattercattabucattailcattails...

If your terminal width was 70 characters, the longest word
(backscattering = 14) plus 2 spaces would dictate 4 columns (70/16 =
4.375), and the correct output is:

Substring to search for: catt
backscatter backscattered backscattering backscatters
bescatter cattabu cattail cattails
cattalo cattaloes cattalos cattan
catted catter catteries cattery
catti cattie cattier catties
cattiest cattily cattimandoo cattiness
catting cattish cattishly cattishness
cattle cattlebush cattlefold cattlegate
cattlehide cattleless cattleman cattlemen
cattleship cattleya cattleyak cattleyas
catty cattycorner cattycornered cattyman
cattyphoid copycatted copycatting discatter
overscatter rescattering scatt scatted
scatter scatterable scatteration scatteraway
scatterbrain scatterbrained scatterbrains scattered
scatteredly scatteredness scatterer scatterers
scattergood scattergram scattergraph scattergun
scattering scatteringly scatterings scatterling
scatterment scattermouch scatterplot scatterplots
scatters scattershot scattersite scattery
scattier scattiest scatting scatts
scatty tomcatted tomcatting unscattered
wildcatted wildcatter wildcatting

91 matches for catt in 0.0417 seconds

Re: Why does C allow structs to have a tag?

<sf1e9g$14$1@z-news.wcss.wroc.pl>

  copy mid

https://www.novabbs.com/devel/article-flat.php?id=17920&group=comp.lang.c#17920

  copy link   Newsgroups: comp.lang.c
Path: i2pn2.org!i2pn.org!news.swapon.de!fu-berlin.de!newsfeed.pionier.net.pl!pwr.wroc.pl!news.wcss.wroc.pl!not-for-mail
From: antis...@math.uni.wroc.pl
Newsgroups: comp.lang.c
Subject: Re: Why does C allow structs to have a tag?
Date: Wed, 11 Aug 2021 21:09:04 +0000 (UTC)
Organization: Politechnika Wroclawska
Lines: 109
Message-ID: <sf1e9g$14$1@z-news.wcss.wroc.pl>
References: <s9iea5$n5c$1@dont-email.me> <sembba$oul$1@dont-email.me> <CrQPI.669$bS5.239@fx21.iad> <seoqf4$pj7$1@dont-email.me> <87czqnlp2m.fsf@bsb.me.uk> <WFWPI.1865$un2.1665@fx04.iad> <FiCQI.401$uk4.259@fx20.iad> <poCQI.37363$EF2.25668@fx47.iad> <VNCQI.5685$Ug5.514@fx24.iad> <seuu75$il3$1@dont-email.me> <TEEQI.5686$Ug5.143@fx24.iad> <GCQQI.17254$lK.16624@fx41.iad> <5d8700fd-6ba7-4c72-ae2f-1d4ea91fe823n@googlegroups.com> <PHRQI.5464$xY.2133@fx05.iad> <sf0re4$v91$1@dont-email.me>
NNTP-Posting-Host: hera.math.uni.wroc.pl
X-Trace: z-news.wcss.wroc.pl 1628716144 36 156.17.86.1 (11 Aug 2021 21:09:04 GMT)
X-Complaints-To: abuse@news.pwr.wroc.pl
NNTP-Posting-Date: Wed, 11 Aug 2021 21:09:04 +0000 (UTC)
Cancel-Lock: sha1:tF3QLT1TJuLHiPbHs/aauowKCPA=
User-Agent: tin/2.4.3-20181224 ("Glen Mhor") (UNIX) (Linux/4.19.0-10-amd64 (x86_64))
 by: antis...@math.uni.wroc.pl - Wed, 11 Aug 2021 21:09 UTC

Bart <bc@freeuk.com> wrote:
> On 11/08/2021 16:06, Scott Lurndal wrote:
> > Malcolm McLean <malcolm.arthur.mclean@gmail.com> writes:
> >> On Wednesday, 11 August 2021 at 14:52:54 UTC+1, Scott Lurndal wrote:
> >>>
> >>> strcat is almost never the right interface to use. It needs
> >>> to scan the entire string to find the terminal nul-byte before
> >>> appending. As the string gets longer, each strcat takes longer
> >>> than the one before.
> >>>
> >>> Just keep a pointer to the next element and increment the
> >>> pointer each time you add a new element.
> >>>
> >> Most strings are short. Building up a url with strcat is not going to
> >> stress a 3GHz machine. If the strings become huge then, yes, you
> >> need to look at more efficient ways of concatenating them.
> >
> > Building it with snprintf() will be far more flexible and efficient.
> >
> > Every cycle matters.
> >
>
>
> Start with this:
>
> char str[100];
> char* s;
>
> Then a loop like this (all unoptimised code to stop it being optimised
> out of existence):

Again this nonsense with unoptimized benchmarks. Write your
benchmark to realisticaly simulate actual load. If you
have real code and compiler optimizes part of it out of
existence, then this is good things, means that task
can be done simpler/faster than what programmer expected.

> for (int i=0; i<10000000; ++i) {
> strcpy(str,"one ");
> strcat(str,"two ");
> strcat(str,"three ");
> strcat(str,"four ");
> strcat(str,"five");
> }
> puts(str);
>
>
> took 1 second (on my Windows PC running tcc). If use sprintf():
>
> for (int i=0; i<10000000; ++i) {
> s=str;
> s+=sprintf(s,"%s","one ");
> s+=sprintf(s,"%s","two ");
> s+=sprintf(s,"%s","three ");
> s+=sprintf(s,"%s","four ");
> sprintf(s,"%s","five");
> }
> puts(s);
>
> then it takes 5.5 seconds. With snprintf() as you suggest, it takes 6.1
> seconds. I thought you said every cycle matters?

On may machine, using cc -O2 I get:

time ./b2
five

real 0m0.049s
user 0m0.044s
sys 0m0.004s

Assembler output for the crucial part is:

movl $10000000, %eax #, ivtmp_1
.p2align 4,,10
.p2align 3
..L2:
movl $8293, %ecx #,
movl $32, %esi #,
subl $1, %eax #, ivtmp_1
movw %si, 18+str(%rip) #, MEM[(void *)&str + 14B]
movl $543518319, str(%rip) #, MEM[(void *)&str]
movl $544175988, 4+str(%rip) #, MEM[(void *)&str + 4B]
movl $1701996660, 8+str(%rip) #, MEM[(void *)&str + 8B]
movw %cx, 12+str(%rip) #, MEM[(void *)&str + 8B]
movl $1920298854, 14+str(%rip) #, MEM[(void *)&str + 14B]
movq %rdx, s(%rip) # tmp98, s
movl $1702259046, 19+str(%rip) #, MEM[(void *)&str + 19B]
movb $0, 23+str(%rip) #, MEM[(void *)&str + 19B]
jne .L2 #,
leaq 19+str(%rip), %rdi #,
call puts@PLT

As you see, there are no call to 'sprintf' but the code is dully
doing all interation that you prescribed and putting characters
in buffer. And FYI, there is no string line "one", ..., etc
in the assembly, all string copying is done via integer moves.

BTW: Even with -O0 (or no optimization flag) is see no calls
to 'sprintf', but loop is slower and take 0.246s. This
is 5 times slower than optimized loop above and clearly
shows that unoptimized benchmarks make no sense.

BTW2: You write code using 'sprintf' if you know that compiler
will optimize it (as it did above). Otherwise look what is
fast in compiler you use (your bcc???).

--
Waldek Hebisch

Re: Why does C allow structs to have a tag?

<sf1ecg$da2$1@dont-email.me>

  copy mid

https://www.novabbs.com/devel/article-flat.php?id=17921&group=comp.lang.c#17921

  copy link   Newsgroups: comp.lang.c
Path: i2pn2.org!i2pn.org!eternal-september.org!reader02.eternal-september.org!.POSTED!not-for-mail
From: bc...@freeuk.com (Bart)
Newsgroups: comp.lang.c
Subject: Re: Why does C allow structs to have a tag?
Date: Wed, 11 Aug 2021 22:10:32 +0100
Organization: A noiseless patient Spider
Lines: 76
Message-ID: <sf1ecg$da2$1@dont-email.me>
References: <s9iea5$n5c$1@dont-email.me> <seejf8$9ti$1@dont-email.me>
<WowPI.4743$NQ1.1007@fx48.iad> <sembba$oul$1@dont-email.me>
<CrQPI.669$bS5.239@fx21.iad> <seoqf4$pj7$1@dont-email.me>
<87czqnlp2m.fsf@bsb.me.uk> <WFWPI.1865$un2.1665@fx04.iad>
<FiCQI.401$uk4.259@fx20.iad> <poCQI.37363$EF2.25668@fx47.iad>
<VNCQI.5685$Ug5.514@fx24.iad> <seuu75$il3$1@dont-email.me>
<TEEQI.5686$Ug5.143@fx24.iad> <GCQQI.17254$lK.16624@fx41.iad>
<5d8700fd-6ba7-4c72-ae2f-1d4ea91fe823n@googlegroups.com>
<PHRQI.5464$xY.2133@fx05.iad> <sf0re4$v91$1@dont-email.me>
<4XVQI.40335$Fx8.28023@fx45.iad>
Mime-Version: 1.0
Content-Type: text/plain; charset=utf-8; format=flowed
Content-Transfer-Encoding: 8bit
Injection-Date: Wed, 11 Aug 2021 21:10:40 -0000 (UTC)
Injection-Info: reader02.eternal-september.org; posting-host="ebac4182797cc3b1d63c47001b000224";
logging-data="13634"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX1/dyy0pcbBOCvWDjDUJ4t1L3F7w0va77UA="
User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:78.0) Gecko/20100101
Thunderbird/78.11.0
Cancel-Lock: sha1:RkVqEUn2lOgC3wPNSRSFdQ8uudA=
In-Reply-To: <4XVQI.40335$Fx8.28023@fx45.iad>
X-Antivirus-Status: Clean
Content-Language: en-GB
X-Antivirus: AVG (VPS 210811-2, 11/8/2021), Outbound message
 by: Bart - Wed, 11 Aug 2021 21:10 UTC

On 11/08/2021 20:55, DFS wrote:
> On 8/11/2021 11:47 AM, Bart wrote:
>
>> Start with this:
>>
>>      char str[100];
>>      char* s;
>>
>> Then a loop like this (all unoptimised code to stop it being optimised
>> out of existence):
>>
>>    for (int i=0; i<10000000; ++i) {
>>        strcpy(str,"one ");
>>        strcat(str,"two ");
>>        strcat(str,"three ");
>>        strcat(str,"four ");
>>        strcat(str,"five");
>>    }
>>    puts(str);
>>
>>
>> took 1 second (on my Windows PC running tcc). If use sprintf():
>>
>>    for (int i=0; i<10000000; ++i) {
>>        s=str;
>>        s+=sprintf(s,"%s","one ");
>>        s+=sprintf(s,"%s","two ");
>>        s+=sprintf(s,"%s","three ");
>>        s+=sprintf(s,"%s","four ");
>>           sprintf(s,"%s","five");
>>    }
>>    puts(s);
>
>
> Did you mean to leave off the s+= in the last line?

Yes; because s is not needed further in that iteration.

(But the last puts should operate on str, not s, which just shows the
last substring.)

>
>
>> then it takes 5.5 seconds. With snprintf() as you suggest, it takes
>> 6.1 seconds. I thought you said every cycle matters?
>
> FWIW: also on Windows
>
> compiled with tcc
> strcat : 0.7s
> sprintf: 6.3s
>
> compiled with Mingw-w64 GCC
> strcat : 0.4s
> sprintf: 4.4s

I was trying to see whether sprintf/snprintf was more efficient than
strcat for concatenating several short strings, as was postulated.

Well, apparently not for strings totalling only 23 characters. Maybe the
differences would be narrower for longer strings, but I tried it with
strings totalling 158 characters, and there was an even wider gap
between the strcat and sprintf loops.

(Note my gcc seems to do a similar trick here as with printf, in using a
version of sprintf which is not the one in msvcrt.dll. One that is about
1/3 faster, but is still significantly slower than strcat for this test.)

This is really not surprising, since strcat can implemented much more
simply than sprintf.

I tried to find a crossover point, a total length of string at which an
sprintf loop was faster than a strcat one, and there wasn't one! At
least not under a 2.5MB total string anyway.

Re: Why does C allow structs to have a tag?

<0nXQI.2130$3w6.1020@fx26.iad>

  copy mid

https://www.novabbs.com/devel/article-flat.php?id=17922&group=comp.lang.c#17922

  copy link   Newsgroups: comp.lang.c
Path: i2pn2.org!i2pn.org!news.swapon.de!news.uzoreto.com!newsfeed.xs4all.nl!newsfeed9.news.xs4all.nl!news-out.netnews.com!news.alt.net!fdc2.netnews.com!peer02.ams1!peer.ams1.xlned.com!news.xlned.com!peer03.iad!feed-me.highwinds-media.com!news.highwinds-media.com!fx26.iad.POSTED!not-for-mail
X-newsreader: xrn 9.03-beta-14-64bit
Sender: scott@dragon.sl.home (Scott Lurndal)
From: sco...@slp53.sl.home (Scott Lurndal)
Reply-To: slp53@pacbell.net
Subject: Re: Why does C allow structs to have a tag?
Newsgroups: comp.lang.c
References: <s9iea5$n5c$1@dont-email.me> <CrQPI.669$bS5.239@fx21.iad> <seoqf4$pj7$1@dont-email.me> <87czqnlp2m.fsf@bsb.me.uk> <sepbrd$vg4$1@dont-email.me> <877dgvljpf.fsf@bsb.me.uk> <2a1b4347-595a-469a-8df1-db64af9896acn@googlegroups.com> <Wg_PI.6656$NQ1.5159@fx48.iad> <94f47c65-5f5f-44d1-bc37-d51155624ae5n@googlegroups.com> <sesbbk$63q$1@dont-email.me> <sf10rj$7g9$1@z-news.wcss.wroc.pl> <sf1712$t4a$1@dont-email.me> <sf1bdc$pa9$1@z-news.wcss.wroc.pl> <8LWQI.11440$fI7.7665@fx33.iad>
Lines: 23
Message-ID: <0nXQI.2130$3w6.1020@fx26.iad>
X-Complaints-To: abuse@usenetserver.com
NNTP-Posting-Date: Wed, 11 Aug 2021 21:33:48 UTC
Organization: UsenetServer - www.usenetserver.com
Date: Wed, 11 Aug 2021 21:33:48 GMT
X-Received-Bytes: 2037
 by: Scott Lurndal - Wed, 11 Aug 2021 21:33 UTC

DFS <nospam@dfs.com> writes:
>On 8/11/2021 4:19 PM, antispam@math.uni.wroc.pl wrote:
>
>> DFS can be excused as he apparently does not know what
>> happened.
>
>I didn't know why at first, but Kaz Kylheku explained it: the speed
>difference in printf() is due to the implementation used in tcc
>(msvcrt.dll) vs that used in mingw gcc.
>
>I tried to find printf() code in the source for gcc 11.1.0, but
>couldn't. Do you know how to find it?

As Keith has attempted to explain to Bart, repeatedly, printf is
not part of the compiler. It is just a library function called
like any other function.

The source for printf will be available in the source package
corresponding to the library that your application links with.

If it's msvcrt.dll, you'll need to ask Microsoft for the source.

https://sourceware.org/git/?p=glibc.git;a=blob;f=stdio-common/printf.c;h=1a98662f9321fae6b04735b99e06a89bef931d51;hb=HEAD

Re: Why does C allow structs to have a tag?

<sf1had$5p9$1@dont-email.me>

  copy mid

https://www.novabbs.com/devel/article-flat.php?id=17923&group=comp.lang.c#17923

  copy link   Newsgroups: comp.lang.c
Path: i2pn2.org!i2pn.org!eternal-september.org!reader02.eternal-september.org!.POSTED!not-for-mail
From: bc...@freeuk.com (Bart)
Newsgroups: comp.lang.c
Subject: Re: Why does C allow structs to have a tag?
Date: Wed, 11 Aug 2021 23:00:37 +0100
Organization: A noiseless patient Spider
Lines: 189
Message-ID: <sf1had$5p9$1@dont-email.me>
References: <s9iea5$n5c$1@dont-email.me> <seejf8$9ti$1@dont-email.me>
<WowPI.4743$NQ1.1007@fx48.iad> <sembba$oul$1@dont-email.me>
<CrQPI.669$bS5.239@fx21.iad> <seoqf4$pj7$1@dont-email.me>
<87czqnlp2m.fsf@bsb.me.uk> <WFWPI.1865$un2.1665@fx04.iad>
<FiCQI.401$uk4.259@fx20.iad> <poCQI.37363$EF2.25668@fx47.iad>
<VNCQI.5685$Ug5.514@fx24.iad> <seuu75$il3$1@dont-email.me>
<TEEQI.5686$Ug5.143@fx24.iad> <GCQQI.17254$lK.16624@fx41.iad>
<5d8700fd-6ba7-4c72-ae2f-1d4ea91fe823n@googlegroups.com>
<PHRQI.5464$xY.2133@fx05.iad> <sf0re4$v91$1@dont-email.me>
<sf1d0q$iiu$1@dont-email.me>
Mime-Version: 1.0
Content-Type: text/plain; charset=utf-8; format=flowed
Content-Transfer-Encoding: 8bit
Injection-Date: Wed, 11 Aug 2021 22:00:45 -0000 (UTC)
Injection-Info: reader02.eternal-september.org; posting-host="99fe37e4e79e4f9d568828aa5779e349";
logging-data="5929"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX18OB4vVFz0GS/iskhos8wSXa4viXb2U6uI="
User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:78.0) Gecko/20100101
Thunderbird/78.11.0
Cancel-Lock: sha1:rlCspguU/F8JZhenXwScYP3we30=
In-Reply-To: <sf1d0q$iiu$1@dont-email.me>
X-Antivirus-Status: Clean
Content-Language: en-GB
X-Antivirus: AVG (VPS 210811-2, 11/8/2021), Outbound message
 by: Bart - Wed, 11 Aug 2021 22:00 UTC

On 11/08/2021 21:47, David Brown wrote:
> On 11/08/2021 17:47, Bart wrote:

>> Start with this:
>>
>>     char str[100];
>>     char* s;
>>
>> Then a loop like this (all unoptimised code to stop it being optimised
>> out of existence):
>
> As you well know, timing unoptimised code is an utterly pointless
> exercise. You need to do something to make sure the operations are
> carried out, such as judicious use of volatile, or using "global"
> variables rather than local ones. Disabling optimisation is like
> comparing the speed of cars while forcing them to remain in first gear.

No, it's ensuring that all of them follow the same route. Otherwise each
will find their own shortcuts, or may not bother going anywhere at all
if they see they're simply going to end up back home anyway.

That's helpful if you're trying to compare different cars or different
routes.

>>
>>   for (int i=0; i<10000000; ++i) {
>>       strcpy(str,"one ");
>>       strcat(str,"two ");
>>       strcat(str,"three ");
>>       strcat(str,"four ");
>>       strcat(str,"five");
>>   }
>>   puts(str);
>>
>>
>> took 1 second (on my Windows PC running tcc). If use sprintf():
>>
>>   for (int i=0; i<10000000; ++i) {
>>       s=str;
>>       s+=sprintf(s,"%s","one ");
>>       s+=sprintf(s,"%s","two ");
>>       s+=sprintf(s,"%s","three ");
>>       s+=sprintf(s,"%s","four ");
>>          sprintf(s,"%s","five");
>>   }
>>   puts(s);
>>
>> then it takes 5.5 seconds. With snprintf() as you suggest, it takes 6.1
>> seconds. I thought you said every cycle matters?
>>
>
> <https://godbolt.org/z/954eccfsM>
>
> gcc (and I really mean gcc - no libraries are involved) generates
> identical code in both cases, and so I would assume (without testing)
> that the speed is the same.

Yeah, but that's taking my test literally, with string literals that the
compiler knows about.

It's possible that a call like sprintf(s, "%s", t) could be optimised
into a strcpy call and even inlined, without needing to know what t is,
however that is not what I'm seeing.

On the following revised test, the string to be concatenated is hidden
from the compiler. The sprintf loop is always slower than the strcat
loop, even using gcc-O3 and clang-O3 and cl /O2.

Maybe on your super-duper computer with link time optimisations and
such, it will be different. But this is what I'm observing with on Windows:

------------------------------------
c.c
------------------------------------

#include <stdio.h>
#include <time.h>
#include <string.h>

extern char* getstr(void);

char str[100000];

int main(void) {
char* s;
int n=1000000;
int t=clock();

for (int i=0; i<n; ++i) {
strcpy(str,getstr());
strcat(str,getstr());
strcat(str,getstr());
strcat(str,getstr());
strcat(str,getstr());
}
puts(str);
printf("%d\n",(int)strlen(str));

printf("time1 %d\n",(int)(clock()-t));
t=clock();

for (int i=0; i<n; ++i) {
s=str;
s+=sprintf(s,"%s",getstr());
s+=sprintf(s,"%s",getstr());
s+=sprintf(s,"%s",getstr());
s+=sprintf(s,"%s",getstr());
sprintf(s,"%s",getstr());
}
puts(str);

printf("%d\n",(int)strlen(str));
printf("time2 %d\n",(int)(clock()-t));

puts("");

}

------------------------------------
d.c
------------------------------------
char* getstr(void){return "ABCDEFGHIJKLMNOPQRSTUVWXYZ ";}

Build as:

gcc -O3 c.c d.c

Run as:

a # or ./a.out on certain OSes

This is what I get on Windows:

------------------------------------------------
C:\c>gcc --version
gcc (tdm64-1) 10.3.0
Copyright (C) 2020 Free Software Foundation, Inc.
<snip>

C:\c>gcc -O3 c.c d.c

C:\c>a
ABCDEFGHIJKLMNOPQRSTUVWXYZ ABCDEFGHIJKLMNOPQRSTUVWXYZ
ABCDEFGHIJKLMNOPQRSTUVWXYZ ABCDEFGHIJKLMNOPQRS
TUVWXYZ ABCDEFGHIJKLMNOPQRSTUVWXYZ
135
time1 144
ABCDEFGHIJKLMNOPQRSTUVWXYZ ABCDEFGHIJKLMNOPQRSTUVWXYZ
ABCDEFGHIJKLMNOPQRSTUVWXYZ ABCDEFGHIJKLMNOPQRS
TUVWXYZ ABCDEFGHIJKLMNOPQRSTUVWXYZ
135
time2 733
------------------------------------------------

clang -O3 gives 196/714.
DMC -o gives 421/1108.
lc -O gives 457/3155.
cl /2 gives 426/742
tcc gives 187/1438
bcc gives 208/1357
gcc -O0 gives 144/865

Finally this loop in my scripting language to do the same task:

function getstr=
"ABCDEFGHIJKLMNOPQRSTUVWXYZ "
end

to 1 million do
s:=getstr()
s+:=getstr()
s+:=getstr()
s+:=getstr()
s+:=getstr()
od

println s
println s.len

took 680ms; faster than gcc-O3 using sprintf.

Someone asserted that using sprintf to do this stuff was more efficient
than strcat; I disagreed. My findings suggested that strcat is faster.

You say your tests (on my program with fixed strings) would have them be
the same speed. So when is sprintf actually faster?

Re: Why does C allow structs to have a tag?

<sf1i29$jdp$1@dont-email.me>

  copy mid

https://www.novabbs.com/devel/article-flat.php?id=17924&group=comp.lang.c#17924

  copy link   Newsgroups: comp.lang.c
Path: i2pn2.org!i2pn.org!eternal-september.org!reader02.eternal-september.org!.POSTED!not-for-mail
From: bc...@freeuk.com (Bart)
Newsgroups: comp.lang.c
Subject: Re: Why does C allow structs to have a tag?
Date: Wed, 11 Aug 2021 23:13:21 +0100
Organization: A noiseless patient Spider
Lines: 279
Message-ID: <sf1i29$jdp$1@dont-email.me>
References: <s9iea5$n5c$1@dont-email.me> <sembba$oul$1@dont-email.me>
<CrQPI.669$bS5.239@fx21.iad> <seoqf4$pj7$1@dont-email.me>
<87czqnlp2m.fsf@bsb.me.uk> <WFWPI.1865$un2.1665@fx04.iad>
<FiCQI.401$uk4.259@fx20.iad> <poCQI.37363$EF2.25668@fx47.iad>
<VNCQI.5685$Ug5.514@fx24.iad> <seuu75$il3$1@dont-email.me>
<TEEQI.5686$Ug5.143@fx24.iad> <GCQQI.17254$lK.16624@fx41.iad>
<5d8700fd-6ba7-4c72-ae2f-1d4ea91fe823n@googlegroups.com>
<PHRQI.5464$xY.2133@fx05.iad> <sf0re4$v91$1@dont-email.me>
<sf1e9g$14$1@z-news.wcss.wroc.pl>
Mime-Version: 1.0
Content-Type: text/plain; charset=utf-8; format=flowed
Content-Transfer-Encoding: 7bit
Injection-Date: Wed, 11 Aug 2021 22:13:29 -0000 (UTC)
Injection-Info: reader02.eternal-september.org; posting-host="99fe37e4e79e4f9d568828aa5779e349";
logging-data="19897"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX1/NgUtqezpdQqbDBVTwTYfGO02xZM0RDN8="
User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:78.0) Gecko/20100101
Thunderbird/78.11.0
Cancel-Lock: sha1:hN6tgGy60Ryj2YzfTcmCpjJTE0s=
In-Reply-To: <sf1e9g$14$1@z-news.wcss.wroc.pl>
X-Antivirus-Status: Clean
Content-Language: en-GB
X-Antivirus: AVG (VPS 210811-2, 11/8/2021), Outbound message
 by: Bart - Wed, 11 Aug 2021 22:13 UTC

On 11/08/2021 22:09, antispam@math.uni.wroc.pl wrote:
> Bart <bc@freeuk.com> wrote:
>> On 11/08/2021 16:06, Scott Lurndal wrote:
>>> Malcolm McLean <malcolm.arthur.mclean@gmail.com> writes:
>>>> On Wednesday, 11 August 2021 at 14:52:54 UTC+1, Scott Lurndal wrote:
>>>>>
>>>>> strcat is almost never the right interface to use. It needs
>>>>> to scan the entire string to find the terminal nul-byte before
>>>>> appending. As the string gets longer, each strcat takes longer
>>>>> than the one before.
>>>>>
>>>>> Just keep a pointer to the next element and increment the
>>>>> pointer each time you add a new element.
>>>>>
>>>> Most strings are short. Building up a url with strcat is not going to
>>>> stress a 3GHz machine. If the strings become huge then, yes, you
>>>> need to look at more efficient ways of concatenating them.
>>>
>>> Building it with snprintf() will be far more flexible and efficient.
>>>
>>> Every cycle matters.
>>>
>>
>>
>> Start with this:
>>
>> char str[100];
>> char* s;
>>
>> Then a loop like this (all unoptimised code to stop it being optimised
>> out of existence):
>
> Again this nonsense with unoptimized benchmarks. Write your
> benchmark to realisticaly simulate actual load. If you
> have real code and compiler optimizes part of it out of
> existence, then this is good things, means that task
> can be done simpler/faster than what programmer expected.

No it is a bad thing. You want such a test to tell you a general thing:
is strcat to concatenate multiple short strings generally better than
multiple calls to sprintf?

That it can optimise both away in this specific, silly benchmark tells
you nothing.

See my reply to David Brown a few minutes ago where I did enable
optimisation on my compilers, with a revised test.

>> for (int i=0; i<10000000; ++i) {
>> strcpy(str,"one ");
>> strcat(str,"two ");
>> strcat(str,"three ");
>> strcat(str,"four ");
>> strcat(str,"five");
>> }
>> puts(str);
>>
>>
>> took 1 second (on my Windows PC running tcc). If use sprintf():
>>
>> for (int i=0; i<10000000; ++i) {
>> s=str;
>> s+=sprintf(s,"%s","one ");
>> s+=sprintf(s,"%s","two ");
>> s+=sprintf(s,"%s","three ");
>> s+=sprintf(s,"%s","four ");
>> sprintf(s,"%s","five");
>> }
>> puts(s);
>>
>> then it takes 5.5 seconds. With snprintf() as you suggest, it takes 6.1
>> seconds. I thought you said every cycle matters?
>
> On may machine, using cc -O2 I get:
>
> time ./b2
> five
>
> real 0m0.049s
> user 0m0.044s
> sys 0m0.004s
>
> Assembler output for the crucial part is:
>
> movl $10000000, %eax #, ivtmp_1
> .p2align 4,,10
> .p2align 3
> .L2:
> movl $8293, %ecx #,
> movl $32, %esi #,
> subl $1, %eax #, ivtmp_1
> movw %si, 18+str(%rip) #, MEM[(void *)&str + 14B]
> movl $543518319, str(%rip) #, MEM[(void *)&str]
> movl $544175988, 4+str(%rip) #, MEM[(void *)&str + 4B]
> movl $1701996660, 8+str(%rip) #, MEM[(void *)&str + 8B]
> movw %cx, 12+str(%rip) #, MEM[(void *)&str + 8B]
> movl $1920298854, 14+str(%rip) #, MEM[(void *)&str + 14B]
> movq %rdx, s(%rip) # tmp98, s
> movl $1702259046, 19+str(%rip) #, MEM[(void *)&str + 19B]
> movb $0, 23+str(%rip) #, MEM[(void *)&str + 19B]
> jne .L2 #,
> leaq 19+str(%rip), %rdi #,
> call puts@PLT

This is what I get for the c.c module of my last past, with gcc -O3 -S
(comments and other noise deleted):

printf:
push r12 #
push rbx #
sub rsp, 56 #,
lea rbx, 88[rsp] # tmp86,
mov QWORD PTR 88[rsp], rdx #,
mov r12, rcx # __format, tmp89
mov ecx, 1 #,
mov QWORD PTR 96[rsp], r8 #,
mov QWORD PTR 104[rsp], r9 #,
mov QWORD PTR 40[rsp], rbx # MEM[(char * *)&__local_argv], tmp86
call [QWORD PTR __imp___acrt_iob_func[rip]] #
mov r8, rbx #, tmp86
mov rdx, r12 #, __format
mov rcx, rax # _2, tmp90
call __mingw_vfprintf #
add rsp, 56 #,
pop rbx #
pop r12 #
ret
..LC0:
sprintf.constprop.0:
sub rsp, 56 #,
lea rdx, .LC0[rip] #,
lea rcx, str[rip] #,
mov QWORD PTR 80[rsp], r8 #,
lea r8, 80[rsp] # tmp86,
mov QWORD PTR 88[rsp], r9 #,
mov QWORD PTR 40[rsp], r8 # MEM[(char * *)&__local_argv], tmp86
call __mingw_vsprintf #
add rsp, 56 #,
ret
sprintf.constprop.1:
sub rsp, 56 #,
lea rdx, .LC0[rip] #,
mov QWORD PTR 80[rsp], r8 #,
lea r8, 80[rsp] # tmp86,
mov QWORD PTR 88[rsp], r9 #,
mov QWORD PTR 40[rsp], r8 # MEM[(char * *)&__local_argv], tmp86
call __mingw_vsprintf #
add rsp, 56 #,
ret
..LC1:
.ascii "%d\12\0"
..LC2:
.ascii "time1 %d\12\0"
..LC3:
.ascii "time2 %d\12\0"
..LC4:
.ascii "\0"
.section .text.startup,"x"
main:
push r13 #
push r12 #
push rbp #
push rdi #
push rsi #
push rbx #
sub rsp, 40 #,
mov esi, 1000000 # ivtmp_24,
lea rbx, str[rip] # tmp134,
call __main #
call clock #
mov edi, eax # t, tmp135
..L6:
call getstr #
mov rcx, rbx #, tmp134
mov rdx, rax # _1, tmp136
call strcpy #
call getstr #
mov rcx, rbx #, tmp134
mov rdx, rax # _2, tmp137
call strcat #
call getstr #
mov rcx, rbx #, tmp134
mov rdx, rax # _3, tmp138
call strcat #
call getstr #
mov rcx, rbx #, tmp134
mov rdx, rax # _4, tmp139
call strcat #
call getstr #
mov rcx, rbx #, tmp134
mov rdx, rax # _5, tmp140
call strcat #
sub esi, 1 # ivtmp_24,
jne .L6 #,
lea rcx, str[rip] #,
lea rbp, str[rip] # tmp131,
call puts #
lea rcx, str[rip] #,
lea rsi, .LC0[rip] # tmp132,
call strlen #
lea rcx, .LC1[rip] #,
mov rdx, rax # tmp118, tmp141
call printf #
call clock #
lea rcx, .LC2[rip] #,
sub eax, edi # tmp142, t
mov edi, 1000000 # ivtmp_23,
mov edx, eax # tmp120, tmp142
call printf #
call clock #
mov r13d, eax # t, tmp143
..L7:
call getstr #
mov rdx, rsi #, tmp132
mov rcx, rbp #, tmp131
mov r8, rax # tmp144,
call sprintf.constprop.0 #
movsx rbx, eax # _43, tmp145
call getstr #
add rbx, rbp # s, tmp131
mov rdx, rsi #, tmp132
mov rcx, rbx #, s
mov r8, rax # tmp146,
call sprintf.constprop.1 #
cdqe
add rbx, rax # s, _47
call getstr #
mov rcx, rbx #, s
mov rdx, rsi #, tmp132
mov r8, rax # tmp148,
call sprintf.constprop.1 #
cdqe
add rbx, rax # s, _51
call getstr #
mov rdx, rsi #, tmp132
mov rcx, rbx #, s
mov r8, rax # tmp150,
call sprintf.constprop.1 #
movsx r12, eax # _55, tmp151
call getstr #
add r12, rbx # s, s
mov rdx, rsi #, tmp132
mov r8, rax # tmp152,
mov rcx, r12 #, s
call sprintf.constprop.1 #
sub edi, 1 # ivtmp_23,
jne .L7 #,
lea rcx, str[rip] #,
call puts #
lea rcx, str[rip] #,
call strlen #
lea rcx, .LC1[rip] #,
mov rdx, rax # tmp127, tmp153
call printf #
call clock #
lea rcx, .LC3[rip] #,
sub eax, r13d # tmp154, t
mov edx, eax # tmp129, tmp154
call printf #
lea rcx, .LC4[rip] #,
call puts #
xor eax, eax #
add rsp, 40 #,
pop rbx #
pop rsi #
pop rdi #
pop rbp #
pop r12 #
pop r13 #
ret
str:
.space 100000
.ident "GCC: (tdm64-1) 10.3.0"


Click here to read the complete article
Re: Why does C allow structs to have a tag?

<sf1j2u$6h1$1@dont-email.me>

  copy mid

https://www.novabbs.com/devel/article-flat.php?id=17925&group=comp.lang.c#17925

  copy link   Newsgroups: comp.lang.c
Path: i2pn2.org!i2pn.org!eternal-september.org!reader02.eternal-september.org!.POSTED!not-for-mail
From: bc...@freeuk.com (Bart)
Newsgroups: comp.lang.c
Subject: Re: Why does C allow structs to have a tag?
Date: Wed, 11 Aug 2021 23:30:46 +0100
Organization: A noiseless patient Spider
Lines: 25
Message-ID: <sf1j2u$6h1$1@dont-email.me>
References: <s9iea5$n5c$1@dont-email.me> <sembba$oul$1@dont-email.me>
<CrQPI.669$bS5.239@fx21.iad> <seoqf4$pj7$1@dont-email.me>
<87czqnlp2m.fsf@bsb.me.uk> <WFWPI.1865$un2.1665@fx04.iad>
<FiCQI.401$uk4.259@fx20.iad> <poCQI.37363$EF2.25668@fx47.iad>
<VNCQI.5685$Ug5.514@fx24.iad> <seuu75$il3$1@dont-email.me>
<TEEQI.5686$Ug5.143@fx24.iad> <GCQQI.17254$lK.16624@fx41.iad>
<5d8700fd-6ba7-4c72-ae2f-1d4ea91fe823n@googlegroups.com>
<PHRQI.5464$xY.2133@fx05.iad> <sf0re4$v91$1@dont-email.me>
<sf1e9g$14$1@z-news.wcss.wroc.pl> <sf1i29$jdp$1@dont-email.me>
Mime-Version: 1.0
Content-Type: text/plain; charset=utf-8; format=flowed
Content-Transfer-Encoding: 8bit
Injection-Date: Wed, 11 Aug 2021 22:30:54 -0000 (UTC)
Injection-Info: reader02.eternal-september.org; posting-host="99fe37e4e79e4f9d568828aa5779e349";
logging-data="6689"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX1/rSbYH79uTlgfv34vL2+eymT4Z3XPSwaQ="
User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:78.0) Gecko/20100101
Thunderbird/78.11.0
Cancel-Lock: sha1:+mj3ByHTsiFBoz07tCAf9BkdUmM=
In-Reply-To: <sf1i29$jdp$1@dont-email.me>
X-Antivirus-Status: Clean
Content-Language: en-GB
X-Antivirus: AVG (VPS 210811-2, 11/8/2021), Outbound message
 by: Bart - Wed, 11 Aug 2021 22:30 UTC

On 11/08/2021 23:13, Bart wrote:
> On 11/08/2021 22:09, antispam@math.uni.wroc.pl wrote:
>> Bart <bc@freeuk.com> wrote:

> This is what I get for the c.c module of my last past, with gcc -O3 -S
> (comments and other noise deleted):
>
> printf:
>     push    r12  #
....
> I guess this is again either all my fault for not knowing what options I
> need to make the code as sweet as yours, or Windows' for being such a
> crap OS, or both.

Better is this godbolt link to that same module (using gcc x64 11.2):

https://godbolt.org/z/Yz9vEzhaY

The displayed code is a lot cleaner and clearer. I'm not even sure what
OS it's for! (It doesn't look like Win64, so at least you can't be
Windows-bashing with it.)

However there are explicit calls to both strcat and sprintf. Changing
the latter to snprintf makes it even longer (not sure how that helps
save cycles as SL said).

Re: Why does C allow structs to have a tag?

<zNYQI.17288$lK.7847@fx41.iad>

  copy mid

https://www.novabbs.com/devel/article-flat.php?id=17926&group=comp.lang.c#17926

  copy link   Newsgroups: comp.lang.c
Path: i2pn2.org!i2pn.org!aioe.org!feeder1.feed.usenet.farm!feed.usenet.farm!newsfeed.xs4all.nl!newsfeed9.news.xs4all.nl!news-out.netnews.com!news.alt.net!fdc2.netnews.com!peer03.ams1!peer.ams1.xlned.com!news.xlned.com!peer03.iad!feed-me.highwinds-media.com!news.highwinds-media.com!fx41.iad.POSTED!not-for-mail
Subject: Re: Why does C allow structs to have a tag?
Newsgroups: comp.lang.c
References: <s9iea5$n5c$1@dont-email.me> <CrQPI.669$bS5.239@fx21.iad>
<seoqf4$pj7$1@dont-email.me> <87czqnlp2m.fsf@bsb.me.uk>
<sepbrd$vg4$1@dont-email.me> <877dgvljpf.fsf@bsb.me.uk>
<2a1b4347-595a-469a-8df1-db64af9896acn@googlegroups.com>
<Wg_PI.6656$NQ1.5159@fx48.iad>
<94f47c65-5f5f-44d1-bc37-d51155624ae5n@googlegroups.com>
<sesbbk$63q$1@dont-email.me> <sf10rj$7g9$1@z-news.wcss.wroc.pl>
<sf1712$t4a$1@dont-email.me> <sf1bdc$pa9$1@z-news.wcss.wroc.pl>
<8LWQI.11440$fI7.7665@fx33.iad> <0nXQI.2130$3w6.1020@fx26.iad>
From: nos...@dfs.com (DFS)
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:78.0) Gecko/20100101
Thunderbird/78.13.0
MIME-Version: 1.0
In-Reply-To: <0nXQI.2130$3w6.1020@fx26.iad>
Content-Type: text/plain; charset=utf-8; format=flowed
Content-Language: en-US
Content-Transfer-Encoding: 7bit
Lines: 33
Message-ID: <zNYQI.17288$lK.7847@fx41.iad>
X-Complaints-To: abuse@blocknews.net
NNTP-Posting-Date: Wed, 11 Aug 2021 23:10:23 UTC
Organization: blocknews - www.blocknews.net
Date: Wed, 11 Aug 2021 19:10:22 -0400
X-Received-Bytes: 2334
 by: DFS - Wed, 11 Aug 2021 23:10 UTC

On 8/11/2021 5:33 PM, Scott Lurndal wrote:
> DFS <nospam@dfs.com> writes:
>> On 8/11/2021 4:19 PM, antispam@math.uni.wroc.pl wrote:
>>
>>> DFS can be excused as he apparently does not know what
>>> happened.
>>
>> I didn't know why at first, but Kaz Kylheku explained it: the speed
>> difference in printf() is due to the implementation used in tcc
>> (msvcrt.dll) vs that used in mingw gcc.
>>
>> I tried to find printf() code in the source for gcc 11.1.0, but
>> couldn't. Do you know how to find it?
>
> As Keith has attempted to explain to Bart, repeatedly, printf is
> not part of the compiler. It is just a library function called
> like any other function.
>
> The source for printf will be available in the source package
> corresponding to the library that your application links with.
>
> If it's msvcrt.dll, you'll need to ask Microsoft for the source.
>
> https://sourceware.org/git/?p=glibc.git;a=blob;f=stdio-common/printf.c;h=1a98662f9321fae6b04735b99e06a89bef931d51;hb=HEAD

Thanks

Re: Why does C allow structs to have a tag?

<sf1qu8$i4i$1@z-news.wcss.wroc.pl>

  copy mid

https://www.novabbs.com/devel/article-flat.php?id=17927&group=comp.lang.c#17927

  copy link   Newsgroups: comp.lang.c
Path: i2pn2.org!i2pn.org!aioe.org!feeder1.feed.usenet.farm!feed.usenet.farm!newsfeed.xs4all.nl!newsfeed8.news.xs4all.nl!news-out.netnews.com!news.alt.net!fdc2.netnews.com!peer02.ams1!peer.ams1.xlned.com!news.xlned.com!peer02.ams4!peer.am4.highwinds-media.com!news.highwinds-media.com!newsfeed.neostrada.pl!unt-exc-02.news.neostrada.pl!newsfeed.pionier.net.pl!pwr.wroc.pl!news.wcss.wroc.pl!not-for-mail
From: antis...@math.uni.wroc.pl
Newsgroups: comp.lang.c
Subject: Re: Why does C allow structs to have a tag?
Date: Thu, 12 Aug 2021 00:44:56 +0000 (UTC)
Organization: Politechnika Wroclawska
Lines: 83
Message-ID: <sf1qu8$i4i$1@z-news.wcss.wroc.pl>
References: <s9iea5$n5c$1@dont-email.me> <seoqf4$pj7$1@dont-email.me> <87czqnlp2m.fsf@bsb.me.uk> <WFWPI.1865$un2.1665@fx04.iad> <FiCQI.401$uk4.259@fx20.iad> <poCQI.37363$EF2.25668@fx47.iad> <VNCQI.5685$Ug5.514@fx24.iad> <seuu75$il3$1@dont-email.me> <TEEQI.5686$Ug5.143@fx24.iad> <GCQQI.17254$lK.16624@fx41.iad> <5d8700fd-6ba7-4c72-ae2f-1d4ea91fe823n@googlegroups.com> <PHRQI.5464$xY.2133@fx05.iad> <sf0re4$v91$1@dont-email.me> <sf1e9g$14$1@z-news.wcss.wroc.pl> <sf1i29$jdp$1@dont-email.me>
NNTP-Posting-Host: hera.math.uni.wroc.pl
X-Trace: z-news.wcss.wroc.pl 1628729096 18578 156.17.86.1 (12 Aug 2021 00:44:56 GMT)
X-Complaints-To: abuse@news.pwr.wroc.pl
NNTP-Posting-Date: Thu, 12 Aug 2021 00:44:56 +0000 (UTC)
Cancel-Lock: sha1:7/J9QKiOPQ37yx3YSQgRfGoQTas=
User-Agent: tin/2.4.3-20181224 ("Glen Mhor") (UNIX) (Linux/4.19.0-10-amd64 (x86_64))
X-Received-Bytes: 4888
 by: antis...@math.uni.wroc.pl - Thu, 12 Aug 2021 00:44 UTC

Bart <bc@freeuk.com> wrote:
> On 11/08/2021 22:09, antispam@math.uni.wroc.pl wrote:
> > Bart <bc@freeuk.com> wrote:
> >> On 11/08/2021 16:06, Scott Lurndal wrote:
> >>> Malcolm McLean <malcolm.arthur.mclean@gmail.com> writes:
> >>>> On Wednesday, 11 August 2021 at 14:52:54 UTC+1, Scott Lurndal wrote:
> >>>>>
> >>>>> strcat is almost never the right interface to use. It needs
> >>>>> to scan the entire string to find the terminal nul-byte before
> >>>>> appending. As the string gets longer, each strcat takes longer
> >>>>> than the one before.
> >>>>>
> >>>>> Just keep a pointer to the next element and increment the
> >>>>> pointer each time you add a new element.
> >>>>>
> >>>> Most strings are short. Building up a url with strcat is not going to
> >>>> stress a 3GHz machine. If the strings become huge then, yes, you
> >>>> need to look at more efficient ways of concatenating them.
> >>>
> >>> Building it with snprintf() will be far more flexible and efficient.
> >>>
> >>> Every cycle matters.
> >>>
> >>
> >>
> >> Start with this:
> >>
> >> char str[100];
> >> char* s;
> >>
> >> Then a loop like this (all unoptimised code to stop it being optimised
> >> out of existence):
> >
> > Again this nonsense with unoptimized benchmarks. Write your
> > benchmark to realisticaly simulate actual load. If you
> > have real code and compiler optimizes part of it out of
> > existence, then this is good things, means that task
> > can be done simpler/faster than what programmer expected.
>
> No it is a bad thing. You want such a test to tell you a general thing:
> is strcat to concatenate multiple short strings generally better than
> multiple calls to sprintf?

AFAICS DFS result showed than on his machine sprintf was
worse. Note I was not the person who advocated use of
'sprintf' -- without testing it is potential trap (as
you and DFS showed). If one wants highest speed, IIRC
BSD folks had a version of strcpy that returned pointer
to destination. This could be fastest, but is nonstandard
so less chance for optimized version in compiler.

> That it can optimise both away in this specific, silly benchmark tells
> you nothing.

Benchmark tells you that compiler can inline very efficient
version of 'sprintf' (and 'strcat') for constant string. This
is important special case that is frequent in practice.

> See my reply to David Brown a few minutes ago where I did enable
> optimisation on my compilers, with a revised test.

Yes, that is valid benchmark. I came to similar benchmark
with similar result, for variable argument 'sprintf' goes
to library routine and at least for short strings is
much slower than 'strcat' or 'strcpy' and 'strlen.
On my machine 'sprintf', 'strcat' and 'strcpy' eventually
arrive to hairy SSE code, which in principle could be
quite fast for long strings, but has significant cost
for short strings (still, library 'strlen' is faster
than inline 'rep scanb' on my machine).

> I guess this is again either all my fault for not knowing what options I
> need to make the code as sweet as yours, or Windows' for being such a
> crap OS, or both.

Well, you used variable strings. In principle gcc could have
an optimized version of 'sprintf' for such case, but it seems
that your or my gcc does not have it. However, the point is
that without turning on optimization on you do not know what
tricks gcc will use to speed up (or not :( ) your program.

--
Waldek Hebisch

Re: Why does C allow structs to have a tag?

<sf2m68$2q5$1@dont-email.me>

  copy mid

https://www.novabbs.com/devel/article-flat.php?id=17930&group=comp.lang.c#17930

  copy link   Newsgroups: comp.lang.c
Path: i2pn2.org!i2pn.org!eternal-september.org!reader02.eternal-september.org!.POSTED!not-for-mail
From: david.br...@hesbynett.no (David Brown)
Newsgroups: comp.lang.c
Subject: Re: Why does C allow structs to have a tag?
Date: Thu, 12 Aug 2021 10:29:59 +0200
Organization: A noiseless patient Spider
Lines: 145
Message-ID: <sf2m68$2q5$1@dont-email.me>
References: <s9iea5$n5c$1@dont-email.me> <seejf8$9ti$1@dont-email.me>
<WowPI.4743$NQ1.1007@fx48.iad> <sembba$oul$1@dont-email.me>
<CrQPI.669$bS5.239@fx21.iad> <seoqf4$pj7$1@dont-email.me>
<87czqnlp2m.fsf@bsb.me.uk> <WFWPI.1865$un2.1665@fx04.iad>
<FiCQI.401$uk4.259@fx20.iad> <poCQI.37363$EF2.25668@fx47.iad>
<VNCQI.5685$Ug5.514@fx24.iad> <seuu75$il3$1@dont-email.me>
<TEEQI.5686$Ug5.143@fx24.iad> <GCQQI.17254$lK.16624@fx41.iad>
<5d8700fd-6ba7-4c72-ae2f-1d4ea91fe823n@googlegroups.com>
<PHRQI.5464$xY.2133@fx05.iad> <sf0re4$v91$1@dont-email.me>
<sf1d0q$iiu$1@dont-email.me> <sf1had$5p9$1@dont-email.me>
Mime-Version: 1.0
Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: 8bit
Injection-Date: Thu, 12 Aug 2021 08:30:00 -0000 (UTC)
Injection-Info: reader02.eternal-september.org; posting-host="87af160eafdf186559d4b8da1e6a6bda";
logging-data="2885"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX18tCUm2PCNo2JuHoOxTZ6FDO+pPLX+P2bs="
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:78.0) Gecko/20100101
Thunderbird/78.11.0
Cancel-Lock: sha1:hjs1q4q+RuFlFqkC+SbtKJO+VO4=
In-Reply-To: <sf1had$5p9$1@dont-email.me>
Content-Language: en-GB
 by: David Brown - Thu, 12 Aug 2021 08:29 UTC

On 12/08/2021 00:00, Bart wrote:
> On 11/08/2021 21:47, David Brown wrote:
>> On 11/08/2021 17:47, Bart wrote:
>
>>> Start with this:
>>>
>>>      char str[100];
>>>      char* s;
>>>
>>> Then a loop like this (all unoptimised code to stop it being optimised
>>> out of existence):
>>
>> As you well know, timing unoptimised code is an utterly pointless
>> exercise.  You need to do something to make sure the operations are
>> carried out, such as judicious use of volatile, or using "global"
>> variables rather than local ones.  Disabling optimisation is like
>> comparing the speed of cars while forcing them to remain in first gear.
>
> No, it's ensuring that all of them follow the same route. Otherwise each
> will find their own shortcuts, or may not bother going anywhere at all
> if they see they're simply going to end up back home anyway.

How many years have you been playing this game? Compilers can do what
they want with the code - whatever flags you give them. Compilers can
and do make optimisations despite your attempts to say "unoptimised".
There is no such thing as "unoptimised" code, just as there is no such
thing as "optimised" code (except in very small test cases). There is
only a question of applying different types of transforms and passes,
and of "trying harder" or not. You don't know the passes and transforms
used by any particular compiler under any given circumstance with any
given piece of code. (I believe that applies even to the tools you
wrote yourself, as you only seem to know what they do by trial and error.)

And when testing the speed of something, you give them a fair chance -
you don't cripple them first.

If you understood more than just your personally self-limited subset of
C, perhaps read a bit of the standards, perhaps listened a bit when
others explain things to you (instead of merely whining about it all
being too complicated or not the way /you/ would have done it), you'd
know this. And you would know how to write code in a way that you can
test the speed of constructs /without/ throwing the baby out with the
bathwater.

>>
>> <https://godbolt.org/z/954eccfsM>
>>
>> gcc (and I really mean gcc - no libraries are involved) generates
>> identical code in both cases, and so I would assume (without testing)
>> that the speed is the same.
>
> Yeah, but that's taking my test literally, with string literals that the
> compiler knows about.
>

Yes. You gave what you thought was a test, and called a test, and I
showed that it is not only irrelevant, but it shows that you were wrong.

Now, /in general/ I would expect strcpy() and other related functions to
be faster than using sprintf or snprintf. I would also expect them to
be inlined much better. But in the particular case of your test, there
is no difference. And in the particular cases Scott had been
discussing, I imagine there are other factors that also mean sprintf is
a more efficient option. (I have no idea what those circumstances might
be - you'd have to ask him - but I doubt if Scott was thinking of code
like yours.)

> It's possible that a call like sprintf(s, "%s", t) could be optimised
> into a strcpy call and even inlined, without needing to know what t is,
> however that is not what I'm seeing.
>
> On the following revised test, the string to be concatenated is hidden
> from the compiler. The sprintf loop is always slower than the strcat
> loop, even using gcc-O3 and clang-O3 and cl /O2.
>
> Maybe on your super-duper computer with link time optimisations and
> such, it will be different. But this is what I'm observing with on Windows:
>

I don't really care what you are getting "on Windows" - you don't know
what you are testing, and don't even understand that you don't know what
you are testing, so the details don't matter. You are not comparing
apples with apples - you are not even comparing apples with oranges.
You are comparing a mystery fruit with another mystery fruit which might
or might not be the same kind.

That is why I used godbolt for looking at the details - there we /do/
know what is being tested, with the results being assembly that we can
compare, dependent on the source code, the compiler chosen, and the
flags - but not libraries, OS's, computers, or any other messy details.
(Obviously such code generation comparisons only work for some kinds of
testing, but they are vastly better than "I tried using some toolchain I
have, but I don't know what it is, how it works or how to use it".)

Your new test code does stop gcc (trunk version, which is a development
version of gcc 12) from turning the sprintf into strcat. Without
knowing any other details, I would expect the sprintf version to be slower.

>
> Someone asserted that using sprintf to do this stuff was more efficient
> than strcat; I disagreed. My findings suggested that strcat is faster.
>

All your findings show is that for your setup and your test programs,
strcat is faster. Neither your setup nor your test program are
realistic for real coding - certainly not in circumstances where the
programmer understands about execution speed and in a program for which
that is important.

Don't get me wrong here - I fully expect that for a simple short test
string, strcat will be faster than sprintf. I just don't think you have
thought about any possible complicating circumstances or effects that
occur in the real programming world, before leaping off with another
"test" program in your eagerness to "prove" someone wrong (and then,
inevitably, to throw in some code in one of your personal languages to
"prove" that it is "better" than C).

> You say your tests (on my program with fixed strings) would have them be
> the same speed. So when is sprintf actually faster?

Since I am not making the claim about sprintf and strcat speeds, and
have not used them in a way that lets me judge their relative speeds in
different circumstances, I can only make some guesses as to when sprintf
might be faster.

First, note that a library implementation of sprintf could quite happily
have an optimisation that first checks if the format string is "%s" and
has dedicated handling for that rather common case. This would mean
sprintf, used like this, would be about as fast as strcpy.

Second, note that if you are dealing with very long strings, then
strcat() must traverse the entire string so far in order to find the
end. The sprintf version does not. As the size of the strings grow,
this traversal will totally dominate the timing, making sprintf faster.

(Even more efficient would be functions like strlcat, or the other
variations that have been made over the years that return more useful
results than strcat that avoid the need to re-establish the length of
the string every time. It would be nice to have seen some of these
standardised and codified in the C standards.)

Re: Why does C allow structs to have a tag?

<sf2mnq$69m$1@dont-email.me>

  copy mid

https://www.novabbs.com/devel/article-flat.php?id=17931&group=comp.lang.c#17931

  copy link   Newsgroups: comp.lang.c
Path: i2pn2.org!i2pn.org!eternal-september.org!reader02.eternal-september.org!.POSTED!not-for-mail
From: david.br...@hesbynett.no (David Brown)
Newsgroups: comp.lang.c
Subject: Re: Why does C allow structs to have a tag?
Date: Thu, 12 Aug 2021 10:39:22 +0200
Organization: A noiseless patient Spider
Lines: 47
Message-ID: <sf2mnq$69m$1@dont-email.me>
References: <s9iea5$n5c$1@dont-email.me> <sembba$oul$1@dont-email.me>
<CrQPI.669$bS5.239@fx21.iad> <seoqf4$pj7$1@dont-email.me>
<87czqnlp2m.fsf@bsb.me.uk> <WFWPI.1865$un2.1665@fx04.iad>
<FiCQI.401$uk4.259@fx20.iad> <poCQI.37363$EF2.25668@fx47.iad>
<VNCQI.5685$Ug5.514@fx24.iad> <seuu75$il3$1@dont-email.me>
<TEEQI.5686$Ug5.143@fx24.iad> <GCQQI.17254$lK.16624@fx41.iad>
<5d8700fd-6ba7-4c72-ae2f-1d4ea91fe823n@googlegroups.com>
<PHRQI.5464$xY.2133@fx05.iad> <sf0re4$v91$1@dont-email.me>
<sf1e9g$14$1@z-news.wcss.wroc.pl> <sf1i29$jdp$1@dont-email.me>
<sf1j2u$6h1$1@dont-email.me>
Mime-Version: 1.0
Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: 8bit
Injection-Date: Thu, 12 Aug 2021 08:39:23 -0000 (UTC)
Injection-Info: reader02.eternal-september.org; posting-host="87af160eafdf186559d4b8da1e6a6bda";
logging-data="6454"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX1+d37y1zJTaBiVNJKAVLBSZs5rJvbybMMw="
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:78.0) Gecko/20100101
Thunderbird/78.11.0
Cancel-Lock: sha1:gCzgY2AUzbKPGYZ3i0kzyhY3Sq4=
In-Reply-To: <sf1j2u$6h1$1@dont-email.me>
Content-Language: en-GB
 by: David Brown - Thu, 12 Aug 2021 08:39 UTC

On 12/08/2021 00:30, Bart wrote:
> On 11/08/2021 23:13, Bart wrote:
>> On 11/08/2021 22:09, antispam@math.uni.wroc.pl wrote:
>>> Bart <bc@freeuk.com> wrote:
>
>> This is what I get for the c.c module of my last past, with gcc -O3 -S
>> (comments and other noise deleted):
>>
>> printf:
>>      push    r12  #
> ...
>> I guess this is again either all my fault for not knowing what options
>> I need to make the code as sweet as yours, or Windows' for being such
>> a crap OS, or both.
>
> Better is this godbolt link to that same module (using gcc x64 11.2):
>
> https://godbolt.org/z/Yz9vEzhaY
>
> The displayed code is a lot cleaner and clearer.

It is not "cleaner and clearer" - it is much messier because you have
put everything into one big function combined with clock timing stuff
and outputs. To make code "clean and clear", structure it properly -
put different things in different functions, and then it is possible to
see the relevant differences in the results.

> I'm not even sure what
> OS it's for! (It doesn't look like Win64, so at least you can't be
> Windows-bashing with it.)

You display your ignorance proudly, as though it were a medal. Bizarre.

If you look at the list of compilers available, it is quickly apparent
that this particular compiler is native gcc on x86 Linux. Other options
available include MSVC running under Wine, and various cross-compilers.

No matter - one of the points of this kind of test is that it is looking
at the compiler output alone, with little or no OS-specific details.

>
> However there are explicit calls to both strcat and sprintf. Changing
> the latter to snprintf makes it even longer (not sure how that helps
> save cycles as SL said).

Yes indeed - after adding the "getstr" to your code, gcc no longer
optimises the code the same way.

Re: Why does C allow structs to have a tag?

<sf2vk1$t6o$1@dont-email.me>

  copy mid

https://www.novabbs.com/devel/article-flat.php?id=17932&group=comp.lang.c#17932

  copy link   Newsgroups: comp.lang.c
Path: i2pn2.org!i2pn.org!eternal-september.org!reader02.eternal-september.org!.POSTED!not-for-mail
From: bc...@freeuk.com (Bart)
Newsgroups: comp.lang.c
Subject: Re: Why does C allow structs to have a tag?
Date: Thu, 12 Aug 2021 12:10:48 +0100
Organization: A noiseless patient Spider
Lines: 133
Message-ID: <sf2vk1$t6o$1@dont-email.me>
References: <s9iea5$n5c$1@dont-email.me> <seejf8$9ti$1@dont-email.me>
<WowPI.4743$NQ1.1007@fx48.iad> <sembba$oul$1@dont-email.me>
<CrQPI.669$bS5.239@fx21.iad> <seoqf4$pj7$1@dont-email.me>
<87czqnlp2m.fsf@bsb.me.uk> <WFWPI.1865$un2.1665@fx04.iad>
<FiCQI.401$uk4.259@fx20.iad> <poCQI.37363$EF2.25668@fx47.iad>
<VNCQI.5685$Ug5.514@fx24.iad> <seuu75$il3$1@dont-email.me>
<TEEQI.5686$Ug5.143@fx24.iad> <GCQQI.17254$lK.16624@fx41.iad>
<5d8700fd-6ba7-4c72-ae2f-1d4ea91fe823n@googlegroups.com>
<PHRQI.5464$xY.2133@fx05.iad> <sf0re4$v91$1@dont-email.me>
<sf1d0q$iiu$1@dont-email.me> <sf1had$5p9$1@dont-email.me>
<sf2m68$2q5$1@dont-email.me>
Mime-Version: 1.0
Content-Type: text/plain; charset=utf-8; format=flowed
Content-Transfer-Encoding: 7bit
Injection-Date: Thu, 12 Aug 2021 11:10:57 -0000 (UTC)
Injection-Info: reader02.eternal-september.org; posting-host="99fe37e4e79e4f9d568828aa5779e349";
logging-data="29912"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX1/BbbnzTCeNHuaIQYtQrSmdcoeVZbf6BO0="
User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:78.0) Gecko/20100101
Thunderbird/78.11.0
Cancel-Lock: sha1:IEi96/8rH0UHOcfmb+FyU+6GGhs=
In-Reply-To: <sf2m68$2q5$1@dont-email.me>
X-Antivirus-Status: Clean
Content-Language: en-GB
X-Antivirus: AVG (VPS 210812-0, 12/8/2021), Outbound message
 by: Bart - Thu, 12 Aug 2021 11:10 UTC

On 12/08/2021 09:29, David Brown wrote:
> On 12/08/2021 00:00, Bart wrote:

> Yes. You gave what you thought was a test, and called a test, and I
> showed that it is not only irrelevant, but it shows that you were wrong.
>
>
> Now, /in general/ I would expect strcpy() and other related functions to
> be faster than using sprintf or snprintf. I would also expect them to
> be inlined much better.

Malcolm suggested that use of strcat was fine for assembling short
strings, SL suggested using snprintf every time because 'every cycle
counts'.

However, if compilers can optimise that aggressively, why don't they
also optimise strcat into sprintf if it is actually faster?

My assumption was that in real code, strcat and sprintf are actually
being called as functions. Specifically, as functions in an internal
library that is already compiled.

In that case, you want to know whether CALLING strcat in a loop was
faster or slower than calling sprintf in a loop.

One way of ensuring that optimisers don't interfere with such code (by
ending up not calling a function, or not doing anything) is to turn off
optimisation. Or by writing a more elaborate test, but even then you can
never be sure what a compiler might sneakily be doing to invalid your tests.

As it turned out, my more elaborate, optimised test confirmed the
results of the simpler, non-optimised one - strcat loops were faster.

(Another way of doing it is to call strcat and sprintf via the FFI of
another language, eg. mine, which also confirmed it.)

>> It's possible that a call like sprintf(s, "%s", t) could be optimised
>> into a strcpy call and even inlined, without needing to know what t is,
>> however that is not what I'm seeing.
>>
>> On the following revised test, the string to be concatenated is hidden
>> from the compiler. The sprintf loop is always slower than the strcat
>> loop, even using gcc-O3 and clang-O3 and cl /O2.
>>
>> Maybe on your super-duper computer with link time optimisations and
>> such, it will be different. But this is what I'm observing with on Windows:
>>
>
> I don't really care what you are getting "on Windows" - you don't know
> what you are testing, and don't even understand that you don't know what
> you are testing, so the details don't matter. You are not comparing
> apples with apples - you are not even comparing apples with oranges.
> You are comparing a mystery fruit with another mystery fruit which might
> or might not be the same kind.
>
> That is why I used godbolt for looking at the details - there we /do/
> know what is being tested,

That doesn't tell you much about non-optimising compilers, or attempts
to call C functions from other languages, which is MY interest.

You may also be distributing C source and don't know what someone is
going to do with it.

The optimisations are just a bonus when you eventually get around to
using an optimising C compiler in some cases, but your program must work
adequately without that.

So please accept that we have different aims and different interests.

> Don't get me wrong here - I fully expect that for a simple short test
> string, strcat will be faster than sprintf.

Try this version of getstr():

char* getstr(void){
enum {N=10000};
static char* s=NULL;

if (s) return s;

s=malloc(N+1);
memset(s,'A',N);
s[N]=0;
return s;
}

You may need to adjust the timing loop in the other module for fewer
iterations, and ensure the str[] array is big enough for 5 copies. (And
maybe comment out the bits that print the strings!)

You might be surprised at the results.

(With N=1000000 here, and 100 iterations, gcc-O3 gave me figures of
440/2320 msec - sprintf was still several times slower.)

> I just don't think you have
> thought about any possible complicating circumstances or effects that
> occur in the real programming world, before leaping off with another
> "test" program in your eagerness to "prove" someone wrong (and then,
> inevitably, to throw in some code in one of your personal languages to
> "prove" that it is "better" than C).

No, I was just fed up with Scott Lurndal treating me with contempt. He
said something I'd challenged then refused to back it up, claiming he
was too busy.

That interpreted code (which uses counted strings) was as fast as the C
loop using sprintf was a bit of a surprise to me, but I found it
interesting to share.

If you don't like me using my personal languge, here it is in Python:

--------------------
def getstr():
return "ABCDEFGHIJKLMNOPQRSTUVWXYZ "

for i in range(1000000):
s=""
s+=getstr()
s+=getstr()
s+=getstr()
s+=getstr()
s+=getstr()

print (s)
print (len(s))
--------------------

This took 1.8 seconds with CPython (1/2 to 1/3 the speed of the sprintf
loop) and 0.2 seconds with PyPy (several times the speed of the C). This
language uses counted strings too.

Re: Why does C allow structs to have a tag?

<sf30he$3gc$1@dont-email.me>

  copy mid

https://www.novabbs.com/devel/article-flat.php?id=17933&group=comp.lang.c#17933

  copy link   Newsgroups: comp.lang.c
Path: i2pn2.org!i2pn.org!eternal-september.org!reader02.eternal-september.org!.POSTED!not-for-mail
From: bc...@freeuk.com (Bart)
Newsgroups: comp.lang.c
Subject: Re: Why does C allow structs to have a tag?
Date: Thu, 12 Aug 2021 12:26:29 +0100
Organization: A noiseless patient Spider
Lines: 58
Message-ID: <sf30he$3gc$1@dont-email.me>
References: <s9iea5$n5c$1@dont-email.me> <sembba$oul$1@dont-email.me>
<CrQPI.669$bS5.239@fx21.iad> <seoqf4$pj7$1@dont-email.me>
<87czqnlp2m.fsf@bsb.me.uk> <WFWPI.1865$un2.1665@fx04.iad>
<FiCQI.401$uk4.259@fx20.iad> <poCQI.37363$EF2.25668@fx47.iad>
<VNCQI.5685$Ug5.514@fx24.iad> <seuu75$il3$1@dont-email.me>
<TEEQI.5686$Ug5.143@fx24.iad> <GCQQI.17254$lK.16624@fx41.iad>
<5d8700fd-6ba7-4c72-ae2f-1d4ea91fe823n@googlegroups.com>
<PHRQI.5464$xY.2133@fx05.iad> <sf0re4$v91$1@dont-email.me>
<sf1e9g$14$1@z-news.wcss.wroc.pl> <sf1i29$jdp$1@dont-email.me>
<sf1j2u$6h1$1@dont-email.me> <sf2mnq$69m$1@dont-email.me>
Mime-Version: 1.0
Content-Type: text/plain; charset=utf-8; format=flowed
Content-Transfer-Encoding: 8bit
Injection-Date: Thu, 12 Aug 2021 11:26:38 -0000 (UTC)
Injection-Info: reader02.eternal-september.org; posting-host="99fe37e4e79e4f9d568828aa5779e349";
logging-data="3596"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX19uc9ZYlmdxvEUl39IQExRPA3pit0fmRto="
User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:78.0) Gecko/20100101
Thunderbird/78.11.0
Cancel-Lock: sha1:QfWqexFZfGNZHWu5Hr9uSAy0o/g=
In-Reply-To: <sf2mnq$69m$1@dont-email.me>
X-Antivirus-Status: Clean
Content-Language: en-GB
X-Antivirus: AVG (VPS 210812-0, 12/8/2021), Outbound message
 by: Bart - Thu, 12 Aug 2021 11:26 UTC

On 12/08/2021 09:39, David Brown wrote:
> On 12/08/2021 00:30, Bart wrote:
>> On 11/08/2021 23:13, Bart wrote:
>>> On 11/08/2021 22:09, antispam@math.uni.wroc.pl wrote:
>>>> Bart <bc@freeuk.com> wrote:
>>
>>> This is what I get for the c.c module of my last past, with gcc -O3 -S
>>> (comments and other noise deleted):
>>>
>>> printf:
>>>      push    r12  #
>> ...
>>> I guess this is again either all my fault for not knowing what options
>>> I need to make the code as sweet as yours, or Windows' for being such
>>> a crap OS, or both.
>>
>> Better is this godbolt link to that same module (using gcc x64 11.2):
>>
>> https://godbolt.org/z/Yz9vEzhaY
>>
>> The displayed code is a lot cleaner and clearer.
>
> It is not "cleaner and clearer" - it is much messier because you have
> put everything into one big function combined with clock timing stuff
> and outputs.

I was talking about the assembly code

To make code "clean and clear", structure it properly -
> put different things in different functions, and then it is possible to
> see the relevant differences in the results.
>
>> I'm not even sure what
>> OS it's for! (It doesn't look like Win64, so at least you can't be
>> Windows-bashing with it.)
>
> You display your ignorance proudly, as though it were a medal. Bizarre.

Ignorance about what? I genuinely don't know what machines these
compilers target, because it doesn't tell you. Not for GCC x64 anyway.

Yes, I can see from the call sequences that it is not Win64 ABI, and is
probably 'SYS V', but that's about it.

The important thing is that it shows more realistic code than you and
antispam posted. It should have been clear that that my original code
could collapse down to nothing if optimised, something I even said would
happen.

You both should instead have put together a more solid test that
compared the merits of strcat and sprintf that would hold up better.

Instead you are just more interested in bart-bashing points.

And in the end, which of those two functions is better; what conclusion
have you reached by trashing my own test? You vaguely suggest that
sprintf is better, but where's your benchmark?

Re: Why does C allow structs to have a tag?

<sf3b5u$eou$1@dont-email.me>

  copy mid

https://www.novabbs.com/devel/article-flat.php?id=17934&group=comp.lang.c#17934

  copy link   Newsgroups: comp.lang.c
Path: i2pn2.org!i2pn.org!eternal-september.org!reader02.eternal-september.org!.POSTED!not-for-mail
From: david.br...@hesbynett.no (David Brown)
Newsgroups: comp.lang.c
Subject: Re: Why does C allow structs to have a tag?
Date: Thu, 12 Aug 2021 16:28:13 +0200
Organization: A noiseless patient Spider
Lines: 215
Message-ID: <sf3b5u$eou$1@dont-email.me>
References: <s9iea5$n5c$1@dont-email.me> <seejf8$9ti$1@dont-email.me>
<WowPI.4743$NQ1.1007@fx48.iad> <sembba$oul$1@dont-email.me>
<CrQPI.669$bS5.239@fx21.iad> <seoqf4$pj7$1@dont-email.me>
<87czqnlp2m.fsf@bsb.me.uk> <WFWPI.1865$un2.1665@fx04.iad>
<FiCQI.401$uk4.259@fx20.iad> <poCQI.37363$EF2.25668@fx47.iad>
<VNCQI.5685$Ug5.514@fx24.iad> <seuu75$il3$1@dont-email.me>
<TEEQI.5686$Ug5.143@fx24.iad> <GCQQI.17254$lK.16624@fx41.iad>
<5d8700fd-6ba7-4c72-ae2f-1d4ea91fe823n@googlegroups.com>
<PHRQI.5464$xY.2133@fx05.iad> <sf0re4$v91$1@dont-email.me>
<sf1d0q$iiu$1@dont-email.me> <sf1had$5p9$1@dont-email.me>
<sf2m68$2q5$1@dont-email.me> <sf2vk1$t6o$1@dont-email.me>
Mime-Version: 1.0
Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: 8bit
Injection-Date: Thu, 12 Aug 2021 14:28:14 -0000 (UTC)
Injection-Info: reader02.eternal-september.org; posting-host="87af160eafdf186559d4b8da1e6a6bda";
logging-data="15134"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX19z//UkSCN3fztn16m/3KfvzB2qpMQdB+k="
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:78.0) Gecko/20100101
Thunderbird/78.11.0
Cancel-Lock: sha1:zSoOwJ+B0N1jlnXofwRpXfsTFi0=
In-Reply-To: <sf2vk1$t6o$1@dont-email.me>
Content-Language: en-GB
 by: David Brown - Thu, 12 Aug 2021 14:28 UTC

On 12/08/2021 13:10, Bart wrote:
> On 12/08/2021 09:29, David Brown wrote:
>> On 12/08/2021 00:00, Bart wrote:
>
>> Yes.  You gave what you thought was a test, and called a test, and I
>> showed that it is not only irrelevant, but it shows that you were wrong.
>>
>>
>> Now, /in general/ I would expect strcpy() and other related functions to
>> be faster than using sprintf or snprintf.  I would also expect them to
>> be inlined much better.
>
> Malcolm suggested that use of strcat was fine for assembling short
> strings, SL suggested using snprintf every time because 'every cycle
> counts'.
>

Other people can answer for their own opinions and comments.

> However, if compilers can optimise that aggressively, why don't they
> also optimise strcat into sprintf if it is actually faster?
>

Did you read what I wrote? It is likely, as far as I can guess, that
sprintf will be faster than strcat in cases where you have long strings
and where the return value from sprintf can be used to avoid re-scanning
strings to find their endpoints. I would imagine that is a little too
niche for optimisations, and would also be dependent on the library
implementation. This makes it very different from optimising library
calls into inlined code or clearly simpler functions.

There are always limits to optimisation - sometimes an optimisation is
theoretically possible, but a given compiler doesn't implement it. And
there are often cases where an optimisation might seem to be obviously
valid, when there are actually good reasons why the compiler can't be
sure the optimisation is correct. The folks that write high-end
compilers are really good at making sure there are no unwarranted
assumptions in their optimisations.

> My assumption was that in real code, strcat and sprintf are actually
> being called as functions. Specifically, as functions in an internal
> library that is already compiled.
>

That was an assumption - it was not a requirement, either from Scott's
posts or from your own test code. If your statements rely on that kind
of thing, say so.

> In that case, you want to know whether CALLING strcat in a loop was
> faster or slower than calling sprintf in a loop.
>
> One way of ensuring that optimisers don't interfere with such code (by
> ending up not calling a function, or not doing anything) is to turn off
> optimisation. Or by writing a more elaborate test, but even then you can
> never be sure what a compiler might sneakily be doing to invalid your
> tests.

Turning off optimisations is a silly way to do this - it is a silly way
to do anything, really. But you didn't learn that the last 99 times it
has come up, so I don't expect you to have a light-bulb moment here either.

>
> As it turned out, my more elaborate, optimised test confirmed the
> results of the simpler, non-optimised one - strcat loops were faster.
>

No one disputes the expected relative speeds of typical library
implementations of strcat and sprintf when dealing with short strings in
code such as these examples. That does not make your tests helpful or
relevant.

>
>>> It's possible that a call like sprintf(s, "%s", t) could be optimised
>>> into a strcpy call and even inlined, without needing to know what t is,
>>> however that is not what I'm seeing.
>>>
>>> On the following revised test, the string to be concatenated is hidden
>>> from the compiler. The sprintf loop is always slower than the strcat
>>> loop, even using gcc-O3 and clang-O3 and cl /O2.
>>>
>>> Maybe on your super-duper computer with link time optimisations and
>>> such, it will be different. But this is what I'm observing with on
>>> Windows:
>>>
>>
>> I don't really care what you are getting "on Windows" - you don't know
>> what you are testing, and don't even understand that you don't know what
>> you are testing, so the details don't matter.  You are not comparing
>> apples with apples - you are not even comparing apples with oranges.
>> You are comparing a mystery fruit with another mystery fruit which might
>> or might not be the same kind.
>>
>> That is why I used godbolt for looking at the details - there we /do/
>> know what is being tested,
>
> That doesn't tell you much about non-optimising compilers, or attempts
> to call C functions from other languages, which is MY interest.

No one (sane and knowledgable) cares about the speed of code generated
by non-optimising compilers, or compilers with the optimisation turned off.

No one (sane and knowledgable) who calls library functions from another
language cares about the results of a compiler running test code - they
care about the /library/, its implementation, and efficiency.

So if you are interested in the performance of strcat and sprintf when
used from a different language, look at the library, not the C compiler.
Examine and test things that are /relevant/, either to the discussions
here or relevant to your own interests.

>
> You may also be distributing C source and don't know what someone is
> going to do with it.
>
> The optimisations are just a bonus when you eventually get around to
> using an optimising C compiler in some cases, but your program must work
> adequately without that.
>
> So please accept that we have different aims and different interests.
>
>> Don't get me wrong here - I fully expect that for a simple short test
>> string, strcat will be faster than sprintf.
>
> Try this version of getstr():
>
>  char* getstr(void){
>      enum {N=10000};
>      static char* s=NULL;
>
>      if (s) return s;
>
>      s=malloc(N+1);
>      memset(s,'A',N);
>      s[N]=0;
>      return s;
>  }
>
> You may need to adjust the timing loop in the other module for fewer
> iterations, and ensure the str[] array is big enough for 5 copies. (And
> maybe comment out the bits that print the strings!)
>
> You might be surprised at the results.
>
> (With N=1000000 here, and 100 iterations, gcc-O3 gave me figures of
> 440/2320 msec - sprintf was still several times slower.)
>

I haven't claimed that sprintf is faster - I merely gave a possible
explanation why it might be faster, for some situations.

But looking at the code generated for your latest change, I notice
something vital - gcc (on godbolt) is converting many of the "strcat"
calls into "stpcpy" calls. stpcpy is not a standard C function, but is
(AFAICS) in POSIX standards. It is like strcpy, except it returns a
pointer to the end of the combined string - and is thus vastly more
efficient in this case.

Try your timings with "-std=c99", which stops gcc from using functions
that are not in the C standard (and, obviously, not in the source code).

There is a suggestion to add stpcpy (and spncpy) to the C standards:

<http://www.open-std.org/jtc1/sc22/wg14/www/docs/n2352.htm>

(These threads do sometimes end up revealing interesting things.)

>
>> I just don't think you have
>> thought about any possible complicating circumstances or effects that
>> occur in the real programming world, before leaping off with another
>> "test" program in your eagerness to "prove" someone wrong (and then,
>> inevitably, to throw in some code in one of your personal languages to
>> "prove" that it is "better" than C).
>
> No, I was just fed up with Scott Lurndal treating me with contempt. He
> said something I'd challenged then refused to back it up, claiming he
> was too busy.
>
> That interpreted code (which uses counted strings) was as fast as the C
> loop using sprintf was a bit of a surprise to me, but I found it
> interesting to share.
>
> If you don't like me using my personal languge, here it is in Python:
>
> --------------------
> def getstr():
>     return "ABCDEFGHIJKLMNOPQRSTUVWXYZ "
>
> for i in range(1000000):
>     s=""
>     s+=getstr()
>     s+=getstr()
>     s+=getstr()
>     s+=getstr()
>     s+=getstr()
>
> print (s)
> print (len(s))
> --------------------
>
> This took 1.8 seconds with CPython (1/2 to 1/3 the speed of the sprintf
> loop) and 0.2 seconds with PyPy (several times the speed of the C). This
> language uses counted strings too.

Python is much more useful as an example, since it is something other
people can and do use.

Counted strings are going to do better in a test like this. There are
many different data structures that can be used to hold string data,
each with their benefits and disadvantages. That is another reason why
blanket statements (whether by you or by Scott) without context about
the relative speed of two functions or techniques are usually
meaningless. You have to compare real-world speeds in the situations
you are using them.


Click here to read the complete article
Re: Why does C allow structs to have a tag?

<sf3c4m$m4h$1@dont-email.me>

  copy mid

https://www.novabbs.com/devel/article-flat.php?id=17935&group=comp.lang.c#17935

  copy link   Newsgroups: comp.lang.c
Path: i2pn2.org!i2pn.org!eternal-september.org!reader02.eternal-september.org!.POSTED!not-for-mail
From: david.br...@hesbynett.no (David Brown)
Newsgroups: comp.lang.c
Subject: Re: Why does C allow structs to have a tag?
Date: Thu, 12 Aug 2021 16:44:37 +0200
Organization: A noiseless patient Spider
Lines: 103
Message-ID: <sf3c4m$m4h$1@dont-email.me>
References: <s9iea5$n5c$1@dont-email.me> <sembba$oul$1@dont-email.me>
<CrQPI.669$bS5.239@fx21.iad> <seoqf4$pj7$1@dont-email.me>
<87czqnlp2m.fsf@bsb.me.uk> <WFWPI.1865$un2.1665@fx04.iad>
<FiCQI.401$uk4.259@fx20.iad> <poCQI.37363$EF2.25668@fx47.iad>
<VNCQI.5685$Ug5.514@fx24.iad> <seuu75$il3$1@dont-email.me>
<TEEQI.5686$Ug5.143@fx24.iad> <GCQQI.17254$lK.16624@fx41.iad>
<5d8700fd-6ba7-4c72-ae2f-1d4ea91fe823n@googlegroups.com>
<PHRQI.5464$xY.2133@fx05.iad> <sf0re4$v91$1@dont-email.me>
<sf1e9g$14$1@z-news.wcss.wroc.pl> <sf1i29$jdp$1@dont-email.me>
<sf1j2u$6h1$1@dont-email.me> <sf2mnq$69m$1@dont-email.me>
<sf30he$3gc$1@dont-email.me>
Mime-Version: 1.0
Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: 8bit
Injection-Date: Thu, 12 Aug 2021 14:44:38 -0000 (UTC)
Injection-Info: reader02.eternal-september.org; posting-host="87af160eafdf186559d4b8da1e6a6bda";
logging-data="22673"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX19BXdG1Zk1n5l5slfxNdQWOTpZ6yfrq4T0="
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:78.0) Gecko/20100101
Thunderbird/78.11.0
Cancel-Lock: sha1:HESQ+/bEaSbu/XdjefRnE+uPNsQ=
In-Reply-To: <sf30he$3gc$1@dont-email.me>
Content-Language: en-GB
 by: David Brown - Thu, 12 Aug 2021 14:44 UTC

On 12/08/2021 13:26, Bart wrote:
> On 12/08/2021 09:39, David Brown wrote:
>> On 12/08/2021 00:30, Bart wrote:
>>> On 11/08/2021 23:13, Bart wrote:
>>>> On 11/08/2021 22:09, antispam@math.uni.wroc.pl wrote:
>>>>> Bart <bc@freeuk.com> wrote:
>>>
>>>> This is what I get for the c.c module of my last past, with gcc -O3 -S
>>>> (comments and other noise deleted):
>>>>
>>>> printf:
>>>>       push    r12  #
>>> ...
>>>> I guess this is again either all my fault for not knowing what options
>>>> I need to make the code as sweet as yours, or Windows' for being such
>>>> a crap OS, or both.
>>>
>>> Better is this godbolt link to that same module (using gcc x64 11.2):
>>>
>>> https://godbolt.org/z/Yz9vEzhaY
>>>
>>> The displayed code is a lot cleaner and clearer.
>>
>> It is not "cleaner and clearer" - it is much messier because you have
>> put everything into one big function combined with clock timing stuff
>> and outputs.
>
> I was talking about the assembly code

The same applies to the assembly code as to the source code here. (That
is not always the case, of course.)

>
>   To make code "clean and clear", structure it properly -
>> put different things in different functions, and then it is possible to
>> see the relevant differences in the results.
>>
>>> I'm not even sure what
>>> OS it's for! (It doesn't look like Win64, so at least you can't be
>>> Windows-bashing with it.)
>>
>> You display your ignorance proudly, as though it were a medal.  Bizarre.
>
> Ignorance about what? I genuinely don't know what machines these
> compilers target, because it doesn't tell you. Not for GCC x64 anyway.
>

It tells you "running under Wine" for the Windows-only compilers. That
should be a big clue. You can also look at the documentation for it.

> Yes, I can see from the call sequences that it is not Win64 ABI, and is
> probably 'SYS V', but that's about it.
>
> The important thing is that it shows more realistic code than you and
> antispam posted. It should have been clear that that my original code
> could collapse down to nothing if optimised, something I even said would
> happen.

No, your later examples are not more realistic than your earlier ones,
and putting the two algorithms into one function along with other
boilerplate code instead of two simple functions (that's what my
complaint was about) is not more realistic in any sense.

Show me a /realistic/ use-case for combining the same simple string to
itself a million times.

>
> You both should instead have put together a more solid test that
> compared the merits of strcat and sprintf that would hold up better.
>

Why? All I was doing was showing that the test you gave was pointless.
The result was that you then produced a slightly less pointless test,
which is an improvement.

> Instead you are just more interested in bart-bashing points.
>
> And in the end, which of those two functions is better; what conclusion
> have you reached by trashing my own test? You vaguely suggest that
> sprintf is better, but where's your benchmark?
>

My conclusion from trashing your test is that your test was pointless.
It gave no indication whether one function was better than the other in
any way. Later modifications to your test showed that strcat was faster
than sprintf in that particular meaningless and unrealistic example.

I don't have /any/ concrete conclusions about the relative speeds of
these functions. I can estimate that in general, strcat will usually be
faster than sprintf as independent library functions, and also that in
some cases sprintf might be faster. And I can certainly conclude that
it will all depend on details of the code, the compiler, optimisations,
library implementations, and no doubt also the system it is running on.

Timing meaningless code is usually pointless. If you have a program
that does a lot of string manipulation, and you have investigated and
discovered that the string manipulation is a serious bottleneck and does
not run as fast as you want, then make timings of different algorithms
and functions for that code. (If the speed is not a problem, then of
course you aim for source-code clarity and maintainability, rather than
speed.)

That is the lesson /you/ should take away from all this.

Re: Why does C allow structs to have a tag?

<a26053df-a375-48b1-a3bd-6e8a1caf4557n@googlegroups.com>

  copy mid

https://www.novabbs.com/devel/article-flat.php?id=17936&group=comp.lang.c#17936

  copy link   Newsgroups: comp.lang.c
X-Received: by 2002:a05:622a:4c7:: with SMTP id q7mr4266308qtx.360.1628780599733;
Thu, 12 Aug 2021 08:03:19 -0700 (PDT)
X-Received: by 2002:ac8:4e48:: with SMTP id e8mr4261861qtw.366.1628780599559;
Thu, 12 Aug 2021 08:03:19 -0700 (PDT)
Path: i2pn2.org!i2pn.org!news.niel.me!usenet.pasdenom.info!usenet-fr.net!proxad.net!feeder1-2.proxad.net!209.85.160.216.MISMATCH!news-out.google.com!nntp.google.com!postnews.google.com!google-groups.googlegroups.com!not-for-mail
Newsgroups: comp.lang.c
Date: Thu, 12 Aug 2021 08:03:19 -0700 (PDT)
In-Reply-To: <sf3b5u$eou$1@dont-email.me>
Injection-Info: google-groups.googlegroups.com; posting-host=2a00:23a8:400a:5601:7cd8:8f36:834d:81cb;
posting-account=Dz2zqgkAAADlK5MFu78bw3ab-BRFV4Qn
NNTP-Posting-Host: 2a00:23a8:400a:5601:7cd8:8f36:834d:81cb
References: <s9iea5$n5c$1@dont-email.me> <seejf8$9ti$1@dont-email.me>
<WowPI.4743$NQ1.1007@fx48.iad> <sembba$oul$1@dont-email.me>
<CrQPI.669$bS5.239@fx21.iad> <seoqf4$pj7$1@dont-email.me> <87czqnlp2m.fsf@bsb.me.uk>
<WFWPI.1865$un2.1665@fx04.iad> <FiCQI.401$uk4.259@fx20.iad>
<poCQI.37363$EF2.25668@fx47.iad> <VNCQI.5685$Ug5.514@fx24.iad>
<seuu75$il3$1@dont-email.me> <TEEQI.5686$Ug5.143@fx24.iad>
<GCQQI.17254$lK.16624@fx41.iad> <5d8700fd-6ba7-4c72-ae2f-1d4ea91fe823n@googlegroups.com>
<PHRQI.5464$xY.2133@fx05.iad> <sf0re4$v91$1@dont-email.me>
<sf1d0q$iiu$1@dont-email.me> <sf1had$5p9$1@dont-email.me> <sf2m68$2q5$1@dont-email.me>
<sf2vk1$t6o$1@dont-email.me> <sf3b5u$eou$1@dont-email.me>
User-Agent: G2/1.0
MIME-Version: 1.0
Message-ID: <a26053df-a375-48b1-a3bd-6e8a1caf4557n@googlegroups.com>
Subject: Re: Why does C allow structs to have a tag?
From: malcolm....@gmail.com (Malcolm McLean)
Injection-Date: Thu, 12 Aug 2021 15:03:19 +0000
Content-Type: text/plain; charset="UTF-8"
 by: Malcolm McLean - Thu, 12 Aug 2021 15:03 UTC

On Thursday, 12 August 2021 at 15:28:27 UTC+1, David Brown wrote:
> On 12/08/2021 13:10, Bart wrote:
> > On 12/08/2021 09:29, David Brown wrote:
> >> On 12/08/2021 00:00, Bart wrote:
> >
> >> Yes. You gave what you thought was a test, and called a test, and I
> >> showed that it is not only irrelevant, but it shows that you were wrong.
> >>
> >>
> >> Now, /in general/ I would expect strcpy() and other related functions to
> >> be faster than using sprintf or snprintf. I would also expect them to
> >> be inlined much better.
> >
> > Malcolm suggested that use of strcat was fine for assembling short
> > strings, SL suggested using snprintf every time because 'every cycle
> > counts'.
> >
> Other people can answer for their own opinions and comments.
>
> Python is much more useful as an example, since it is something other
> people can and do use.
>
> Counted strings are going to do better in a test like this. There are
> many different data structures that can be used to hold string data,
> each with their benefits and disadvantages. That is another reason why
> blanket statements (whether by you or by Scott) without context about
> the relative speed of two functions or techniques are usually
> meaningless. You have to compare real-world speeds in the situations
> you are using them.
>
Very few people use C for heavy string processing. They use C for a little bit
of minor string processing in programs which are basically doing something
else. And, interestingly enough, C is a good choice for implementing a
string processing package itself. But C isn't a good choice for the application-
specific code which calls that string processing package.

If you are just doing minor string processing, efficiency doesn't matter. The processing
time wil be dominated by other things, or it will be so short that it's not an issue
at all. Not all cycles are equal, because most machines spend a lot of cycles
idling. Only a cycle which the user/customer notices is worth eliminating.

If you are doing major string processing, my experience here is with bioinformatics,
where data is often either large numbers (tens of thousands) of strings representing
genes, of a few hundred to low thousands of characters long, or small numbers (tens)
of string representing entire neucleotide sequences, which can be up to a billion
characters long (the human genome is 3,000 mega base pairs, spread over 22 normal
chromosomes and two sex chromosomes). However time pressures aren't tight -
a few hours to do an analysis might not be good, but it's not catastrophic. In practise
you need to avoid N by N operations. I used MatLab, because it was lab policy that
everyone used MatLab, not because of its string handling capabilities.

Re: Why does C allow structs to have a tag?

<qtbRI.4636$Mc.1527@fx34.iad>

  copy mid

https://www.novabbs.com/devel/article-flat.php?id=17937&group=comp.lang.c#17937

  copy link   Newsgroups: comp.lang.c
Path: i2pn2.org!i2pn.org!aioe.org!news.uzoreto.com!news-out.netnews.com!news.alt.net!fdc2.netnews.com!peer03.ams1!peer.ams1.xlned.com!news.xlned.com!peer01.iad!feed-me.highwinds-media.com!news.highwinds-media.com!fx34.iad.POSTED!not-for-mail
X-newsreader: xrn 9.03-beta-14-64bit
Sender: scott@dragon.sl.home (Scott Lurndal)
From: sco...@slp53.sl.home (Scott Lurndal)
Reply-To: slp53@pacbell.net
Subject: Re: Why does C allow structs to have a tag?
Newsgroups: comp.lang.c
References: <s9iea5$n5c$1@dont-email.me> <FiCQI.401$uk4.259@fx20.iad> <poCQI.37363$EF2.25668@fx47.iad> <VNCQI.5685$Ug5.514@fx24.iad> <seuu75$il3$1@dont-email.me> <TEEQI.5686$Ug5.143@fx24.iad> <GCQQI.17254$lK.16624@fx41.iad> <5d8700fd-6ba7-4c72-ae2f-1d4ea91fe823n@googlegroups.com> <PHRQI.5464$xY.2133@fx05.iad> <sf0re4$v91$1@dont-email.me> <sf1d0q$iiu$1@dont-email.me> <sf1had$5p9$1@dont-email.me> <sf2m68$2q5$1@dont-email.me> <sf2vk1$t6o$1@dont-email.me> <sf3b5u$eou$1@dont-email.me>
Lines: 23
Message-ID: <qtbRI.4636$Mc.1527@fx34.iad>
X-Complaints-To: abuse@usenetserver.com
NNTP-Posting-Date: Thu, 12 Aug 2021 15:52:54 UTC
Organization: UsenetServer - www.usenetserver.com
Date: Thu, 12 Aug 2021 15:52:54 GMT
X-Received-Bytes: 1987
 by: Scott Lurndal - Thu, 12 Aug 2021 15:52 UTC

David Brown <david.brown@hesbynett.no> writes:
>On 12/08/2021 13:10, Bart wrote:
>> On 12/08/2021 09:29, David Brown wrote:
>>> On 12/08/2021 00:00, Bart wrote:
>>
>>> Yes.  You gave what you thought was a test, and called a test, and I
>>> showed that it is not only irrelevant, but it shows that you were wrong.
>>>
>>>
>>> Now, /in general/ I would expect strcpy() and other related functions to
>>> be faster than using sprintf or snprintf.  I would also expect them to
>>> be inlined much better.
>>
>> Malcolm suggested that use of strcat was fine for assembling short
>> strings, SL suggested using snprintf every time because 'every cycle
>> counts'.
>>
>
>Other people can answer for their own opinions and comments.

Except I have no interest in arguing with Bart. Particularly when
he misrepresents what I said by conflating two different arguments.

Re: Why does C allow structs to have a tag?

<sf3g9s$jqi$1@dont-email.me>

  copy mid

https://www.novabbs.com/devel/article-flat.php?id=17938&group=comp.lang.c#17938

  copy link   Newsgroups: comp.lang.c
Path: i2pn2.org!i2pn.org!eternal-september.org!reader02.eternal-september.org!.POSTED!not-for-mail
From: david.br...@hesbynett.no (David Brown)
Newsgroups: comp.lang.c
Subject: Re: Why does C allow structs to have a tag?
Date: Thu, 12 Aug 2021 17:55:40 +0200
Organization: A noiseless patient Spider
Lines: 27
Message-ID: <sf3g9s$jqi$1@dont-email.me>
References: <s9iea5$n5c$1@dont-email.me> <FiCQI.401$uk4.259@fx20.iad>
<poCQI.37363$EF2.25668@fx47.iad> <VNCQI.5685$Ug5.514@fx24.iad>
<seuu75$il3$1@dont-email.me> <TEEQI.5686$Ug5.143@fx24.iad>
<GCQQI.17254$lK.16624@fx41.iad>
<5d8700fd-6ba7-4c72-ae2f-1d4ea91fe823n@googlegroups.com>
<PHRQI.5464$xY.2133@fx05.iad> <sf0re4$v91$1@dont-email.me>
<sf1d0q$iiu$1@dont-email.me> <sf1had$5p9$1@dont-email.me>
<sf2m68$2q5$1@dont-email.me> <sf2vk1$t6o$1@dont-email.me>
<sf3b5u$eou$1@dont-email.me> <qtbRI.4636$Mc.1527@fx34.iad>
Mime-Version: 1.0
Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: 8bit
Injection-Date: Thu, 12 Aug 2021 15:55:40 -0000 (UTC)
Injection-Info: reader02.eternal-september.org; posting-host="87af160eafdf186559d4b8da1e6a6bda";
logging-data="20306"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX1+qcw9TYzUMCNCna1TjuhChWAJOzq3PvB4="
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:78.0) Gecko/20100101
Thunderbird/78.11.0
Cancel-Lock: sha1:dNVNgdqlVfX/F54Sqy8XNERdGas=
In-Reply-To: <qtbRI.4636$Mc.1527@fx34.iad>
Content-Language: en-GB
 by: David Brown - Thu, 12 Aug 2021 15:55 UTC

On 12/08/2021 17:52, Scott Lurndal wrote:
> David Brown <david.brown@hesbynett.no> writes:
>> On 12/08/2021 13:10, Bart wrote:
>>> On 12/08/2021 09:29, David Brown wrote:
>>>> On 12/08/2021 00:00, Bart wrote:
>>>
>>>> Yes.  You gave what you thought was a test, and called a test, and I
>>>> showed that it is not only irrelevant, but it shows that you were wrong.
>>>>
>>>>
>>>> Now, /in general/ I would expect strcpy() and other related functions to
>>>> be faster than using sprintf or snprintf.  I would also expect them to
>>>> be inlined much better.
>>>
>>> Malcolm suggested that use of strcat was fine for assembling short
>>> strings, SL suggested using snprintf every time because 'every cycle
>>> counts'.
>>>
>>
>> Other people can answer for their own opinions and comments.
>
> Except I have no interest in arguing with Bart. Particularly when
> he misrepresents what I said by conflating two different arguments.
>

Fair enough. If you think expanding on your posts might be of interest
to others here, then please do so.

Re: Why does C allow structs to have a tag?

<sf3ggk$m9i$1@dont-email.me>

  copy mid

https://www.novabbs.com/devel/article-flat.php?id=17939&group=comp.lang.c#17939

  copy link   Newsgroups: comp.lang.c
Path: i2pn2.org!i2pn.org!eternal-september.org!reader02.eternal-september.org!.POSTED!not-for-mail
From: bc...@freeuk.com (Bart)
Newsgroups: comp.lang.c
Subject: Re: Why does C allow structs to have a tag?
Date: Thu, 12 Aug 2021 16:59:07 +0100
Organization: A noiseless patient Spider
Lines: 76
Message-ID: <sf3ggk$m9i$1@dont-email.me>
References: <s9iea5$n5c$1@dont-email.me> <seejf8$9ti$1@dont-email.me>
<WowPI.4743$NQ1.1007@fx48.iad> <sembba$oul$1@dont-email.me>
<CrQPI.669$bS5.239@fx21.iad> <seoqf4$pj7$1@dont-email.me>
<87czqnlp2m.fsf@bsb.me.uk> <WFWPI.1865$un2.1665@fx04.iad>
<FiCQI.401$uk4.259@fx20.iad> <poCQI.37363$EF2.25668@fx47.iad>
<VNCQI.5685$Ug5.514@fx24.iad> <seuu75$il3$1@dont-email.me>
<TEEQI.5686$Ug5.143@fx24.iad> <GCQQI.17254$lK.16624@fx41.iad>
<5d8700fd-6ba7-4c72-ae2f-1d4ea91fe823n@googlegroups.com>
<PHRQI.5464$xY.2133@fx05.iad> <sf0re4$v91$1@dont-email.me>
<sf1d0q$iiu$1@dont-email.me> <sf1had$5p9$1@dont-email.me>
<sf2m68$2q5$1@dont-email.me> <sf2vk1$t6o$1@dont-email.me>
<sf3b5u$eou$1@dont-email.me>
Mime-Version: 1.0
Content-Type: text/plain; charset=utf-8; format=flowed
Content-Transfer-Encoding: 7bit
Injection-Date: Thu, 12 Aug 2021 15:59:16 -0000 (UTC)
Injection-Info: reader02.eternal-september.org; posting-host="99fe37e4e79e4f9d568828aa5779e349";
logging-data="22834"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX19j+BhflmHwPsoQL/kftXVsOHTuIIQnPa0="
User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:78.0) Gecko/20100101
Thunderbird/78.11.0
Cancel-Lock: sha1:WFuELVj5jCCO9JB/ChoOFU7lWXc=
In-Reply-To: <sf3b5u$eou$1@dont-email.me>
X-Antivirus-Status: Clean
Content-Language: en-GB
X-Antivirus: AVG (VPS 210812-0, 12/8/2021), Outbound message
 by: Bart - Thu, 12 Aug 2021 15:59 UTC

On 12/08/2021 15:28, David Brown wrote:
> On 12/08/2021 13:10, Bart wrote:

>> That doesn't tell you much about non-optimising compilers, or attempts
>> to call C functions from other languages, which is MY interest.
>
> No one (sane and knowledgable) cares about the speed of code generated
> by non-optimising compilers, or compilers with the optimisation turned off.
>
> No one (sane and knowledgable) who calls library functions from another
> language cares about the results of a compiler running test code - they
> care about the /library/, its implementation, and efficiency.

That is just your opinion. Many of us do care about it, since
unoptimised code can give highly useful trade-offs (like 100 times
faster build speeds - ask any Rust developer whether they would like a
100x faster build just once).

Any native code non-optimising compiler can still generate code that
will wipe the floor with any interpreted scripting language.

So there is a place for such implementations.

(I'd also imagine that my non-optimising compilers would generate faster
code on your machine, than gcc-O3 on mine.)

> So if you are interested in the performance of strcat and sprintf when
> used from a different language, look at the library, not the C compiler.

You could just write a benchmark if the results are actually in dispute.
Just stating an opinion wouldn't be enough for Scott, but then neither
are hard facts apparently.

>> (With N=1000000 here, and 100 iterations, gcc-O3 gave me figures of
>> 440/2320 msec - sprintf was still several times slower.)
>>
>
> I haven't claimed that sprintf is faster - I merely gave a possible
> explanation why it might be faster, for some situations.

You said it's probably faster for short strings. It seems it can be
faster for much longer ones, but presumably not quoye as long as DFS's.

> But looking at the code generated for your latest change, I notice
> something vital - gcc (on godbolt) is converting many of the "strcat"
> calls into "stpcpy" calls. stpcpy is not a standard C function, but is
> (AFAICS) in POSIX standards. It is like strcpy, except it returns a
> pointer to the end of the combined string - and is thus vastly more
> efficient in this case.

strcat is a very simple function - at least in spec - and thus could
lend itself easily to optimisation.

I use it extensively from outside of C, but usually in cases that are
not speed-critical (such as generating diagnostic listings, or
synthesising command strings for system()).

But I rarely use any *printf functions via FFIs; format strings just
don't belong outside of C.

For building text files in-memory by concatenating, a method I also use
all the time, I use streamlined functions of my own.

> That is another reason why
> blanket statements (whether by you or by Scott) without context about
> the relative speed of two functions or techniques are usually
> meaningless. You have to compare real-world speeds in the situations
> you are using them.

Funny how one remark by Scott that was likely erroneous and misleading
attracts virtually no comment. But someone TRIES to show that they are
wrong, and you try to annihilate them.

Re: Why does C allow structs to have a tag?

<sf3h1q$cdn$2@z-news.wcss.wroc.pl>

  copy mid

https://www.novabbs.com/devel/article-flat.php?id=17940&group=comp.lang.c#17940

  copy link   Newsgroups: comp.lang.c
Path: i2pn2.org!i2pn.org!aioe.org!news.uzoreto.com!fdc3.netnews.com!news-out.netnews.com!news.alt.net!fdc2.netnews.com!peer01.ams1!peer.ams1.xlned.com!news.xlned.com!peer02.ams4!peer.am4.highwinds-media.com!news.highwinds-media.com!newsfeed.neostrada.pl!unt-exc-02.news.neostrada.pl!newsfeed.pionier.net.pl!pwr.wroc.pl!news.wcss.wroc.pl!not-for-mail
From: antis...@math.uni.wroc.pl
Newsgroups: comp.lang.c
Subject: Re: Why does C allow structs to have a tag?
Date: Thu, 12 Aug 2021 16:08:26 +0000 (UTC)
Organization: Politechnika Wroclawska
Lines: 32
Message-ID: <sf3h1q$cdn$2@z-news.wcss.wroc.pl>
References: <s9iea5$n5c$1@dont-email.me> <CrQPI.669$bS5.239@fx21.iad> <seoqf4$pj7$1@dont-email.me> <87czqnlp2m.fsf@bsb.me.uk> <sepbrd$vg4$1@dont-email.me> <877dgvljpf.fsf@bsb.me.uk> <2a1b4347-595a-469a-8df1-db64af9896acn@googlegroups.com> <Wg_PI.6656$NQ1.5159@fx48.iad> <94f47c65-5f5f-44d1-bc37-d51155624ae5n@googlegroups.com> <sesbbk$63q$1@dont-email.me> <sf10rj$7g9$1@z-news.wcss.wroc.pl> <sf1712$t4a$1@dont-email.me> <sf1bdc$pa9$1@z-news.wcss.wroc.pl> <8LWQI.11440$fI7.7665@fx33.iad>
NNTP-Posting-Host: hera.math.uni.wroc.pl
X-Trace: z-news.wcss.wroc.pl 1628784506 12727 156.17.86.1 (12 Aug 2021 16:08:26 GMT)
X-Complaints-To: abuse@news.pwr.wroc.pl
NNTP-Posting-Date: Thu, 12 Aug 2021 16:08:26 +0000 (UTC)
Cancel-Lock: sha1:g64XVkzlEinShvT59L7NMnEP1CY=
User-Agent: tin/2.4.3-20181224 ("Glen Mhor") (UNIX) (Linux/4.19.0-10-amd64 (x86_64))
X-Received-Bytes: 2684
 by: antis...@math.uni.wroc.pl - Thu, 12 Aug 2021 16:08 UTC

DFS <nospam@dfs.com> wrote:
> On 8/11/2021 4:19 PM, antispam@math.uni.wroc.pl wrote:
>
> > DFS can be excused as he apparently does not know what
> > happened.
>
> I didn't know why at first, but Kaz Kylheku explained it: the speed
> difference in printf() is due to the implementation used in tcc
> (msvcrt.dll) vs that used in mingw gcc.

That is the trigger. But when you outut to Windows console
almost all time is spent in console code and graphic
processing (possibly inside a GPU). IIRC other folks noted
that char-by-char output slows console quite a lot. Outputting
to a file is simple way to isolate console effects, even with
char-by-char (unbuffered) output file will be much faster
than console (of course, exact speed will depend in speed
of system callse).

> I tried to find printf() code in the source for gcc 11.1.0, but
> couldn't. Do you know how to find it?

As other explained, printf is library function so you should look
for sources of library that you use (but apparently, on Windows
after some intial stage it will go to closed-source Microsoft library).

Inside gcc you may search for 'builtin_printf'. In particular,
gcc may optimize some prinft variants to simpler versions.
In older versions of gcc relevant file was 'gcc/builtins.c'.

--
Waldek Hebisch

Re: Why does C allow structs to have a tag?

<sf3hoa$vto$1@dont-email.me>

  copy mid

https://www.novabbs.com/devel/article-flat.php?id=17941&group=comp.lang.c#17941

  copy link   Newsgroups: comp.lang.c
Path: i2pn2.org!i2pn.org!eternal-september.org!reader02.eternal-september.org!.POSTED!not-for-mail
From: bc...@freeuk.com (Bart)
Newsgroups: comp.lang.c
Subject: Re: Why does C allow structs to have a tag?
Date: Thu, 12 Aug 2021 17:20:17 +0100
Organization: A noiseless patient Spider
Lines: 35
Message-ID: <sf3hoa$vto$1@dont-email.me>
References: <s9iea5$n5c$1@dont-email.me> <sembba$oul$1@dont-email.me>
<CrQPI.669$bS5.239@fx21.iad> <seoqf4$pj7$1@dont-email.me>
<87czqnlp2m.fsf@bsb.me.uk> <WFWPI.1865$un2.1665@fx04.iad>
<FiCQI.401$uk4.259@fx20.iad> <poCQI.37363$EF2.25668@fx47.iad>
<VNCQI.5685$Ug5.514@fx24.iad> <seuu75$il3$1@dont-email.me>
<TEEQI.5686$Ug5.143@fx24.iad> <GCQQI.17254$lK.16624@fx41.iad>
<5d8700fd-6ba7-4c72-ae2f-1d4ea91fe823n@googlegroups.com>
<PHRQI.5464$xY.2133@fx05.iad> <sf0re4$v91$1@dont-email.me>
<sf1e9g$14$1@z-news.wcss.wroc.pl> <sf1i29$jdp$1@dont-email.me>
<sf1j2u$6h1$1@dont-email.me> <sf2mnq$69m$1@dont-email.me>
<sf30he$3gc$1@dont-email.me> <sf3c4m$m4h$1@dont-email.me>
Mime-Version: 1.0
Content-Type: text/plain; charset=utf-8; format=flowed
Content-Transfer-Encoding: 7bit
Injection-Date: Thu, 12 Aug 2021 16:20:26 -0000 (UTC)
Injection-Info: reader02.eternal-september.org; posting-host="99fe37e4e79e4f9d568828aa5779e349";
logging-data="32696"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX1+v1rtWD0DAhWJUxo5pPt4jC5hWocou/MM="
User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:78.0) Gecko/20100101
Thunderbird/78.11.0
Cancel-Lock: sha1:BBJxV/msFSGD312WpeoQH6/4d7s=
In-Reply-To: <sf3c4m$m4h$1@dont-email.me>
X-Antivirus-Status: Clean
Content-Language: en-GB
X-Antivirus: AVG (VPS 210812-0, 12/8/2021), Outbound message
 by: Bart - Thu, 12 Aug 2021 16:20 UTC

On 12/08/2021 15:44, David Brown wrote:
> On 12/08/2021 13:26, Bart wrote:

> Show me a /realistic/ use-case for combining the same simple string to
> itself a million times.

Show me a use-case for testing vehicles by driving round and round the
same circular track.

It seems you just don't get benchmarks. Many are necessarily repetitive,
and need to concentrate on a specific thing that is being tested. And
all are meaningless.

I could change my getstr() routine to return a random string of random
length, but that makes it harder to measure and compare results, and you
would just find another reason to discredit it.

Here's a challenge for you: some students each present you with an
opaque implementation of [for example] strcat (but renamed to avoid
confusion). You need to grade according them according to how efficient
(ie. how fast) they are on a range of test inputs.

How would you go about testing them? Don't forget you're not allowed to
use loops, or apply the same inputs more than once.

How would you distinguish an entry which is fast because of technique,
from one which is fast because of a clever compiler which can take
advantage of the specific test context?

What would you think of a compiler smart enough to recognise the
function as doing what strcat does, and replaces it with the
highly-optimised built-in strcat; would you consider that a good or bad
thing, from the point of view of doing your job?

Re: Why does C allow structs to have a tag?

<sf3jjj$kbl$1@z-news.wcss.wroc.pl>

  copy mid

https://www.novabbs.com/devel/article-flat.php?id=17942&group=comp.lang.c#17942

  copy link   Newsgroups: comp.lang.c
Path: i2pn2.org!i2pn.org!weretis.net!feeder6.news.weretis.net!panix!1.us.feeder.erje.net!feeder.erje.net!newsfeed.pionier.net.pl!pwr.wroc.pl!news.wcss.wroc.pl!not-for-mail
From: antis...@math.uni.wroc.pl
Newsgroups: comp.lang.c
Subject: Re: Why does C allow structs to have a tag?
Date: Thu, 12 Aug 2021 16:52:03 +0000 (UTC)
Organization: Politechnika Wroclawska
Lines: 110
Message-ID: <sf3jjj$kbl$1@z-news.wcss.wroc.pl>
References: <s9iea5$n5c$1@dont-email.me> <WFWPI.1865$un2.1665@fx04.iad> <FiCQI.401$uk4.259@fx20.iad> <poCQI.37363$EF2.25668@fx47.iad> <VNCQI.5685$Ug5.514@fx24.iad> <seuu75$il3$1@dont-email.me> <TEEQI.5686$Ug5.143@fx24.iad> <GCQQI.17254$lK.16624@fx41.iad> <5d8700fd-6ba7-4c72-ae2f-1d4ea91fe823n@googlegroups.com> <PHRQI.5464$xY.2133@fx05.iad> <sf0re4$v91$1@dont-email.me> <sf1d0q$iiu$1@dont-email.me> <sf1had$5p9$1@dont-email.me> <sf2m68$2q5$1@dont-email.me> <sf2vk1$t6o$1@dont-email.me>
NNTP-Posting-Host: hera.math.uni.wroc.pl
X-Trace: z-news.wcss.wroc.pl 1628787123 20853 156.17.86.1 (12 Aug 2021 16:52:03 GMT)
X-Complaints-To: abuse@news.pwr.wroc.pl
NNTP-Posting-Date: Thu, 12 Aug 2021 16:52:03 +0000 (UTC)
Cancel-Lock: sha1:6rW6qM5Wi+ID6YMLV69CBP7PuuU=
User-Agent: tin/2.4.3-20181224 ("Glen Mhor") (UNIX) (Linux/4.19.0-10-amd64 (x86_64))
 by: antis...@math.uni.wroc.pl - Thu, 12 Aug 2021 16:52 UTC

Bart <bc@freeuk.com> wrote:
> On 12/08/2021 09:29, David Brown wrote:
> > On 12/08/2021 00:00, Bart wrote:
>
> Try this version of getstr():
>
> char* getstr(void){
> enum {N=10000};
> static char* s=NULL;
>
> if (s) return s;
>
> s=malloc(N+1);
> memset(s,'A',N);
> s[N]=0;
> return s;
> }
>
> You may need to adjust the timing loop in the other module for fewer
> iterations, and ensure the str[] array is big enough for 5 copies. (And
> maybe comment out the bits that print the strings!)

I used the following with 'strcpy' and 'strlen':

#include <stdio.h>
#include <string.h>

char str[60*1000];

extern char * get_str(void);

int
main(void) {
char * s;
char * ns;
for (int i=0; i<100000; ++i) {
ns = get_str();
s = str;
strcpy(s, ns);
s += strlen(ns);
strcpy(s, ns);
s += strlen(ns);
strcpy(s, ns);
s += strlen(ns);
strcpy(s, ns);
s += strlen(ns);
strcpy(s, ns);
}
puts(str);
return 0;
}

but redirected output to '/dev/null'.

time ./b5a > /dev/null

real 0m0.400s
user 0m0.400s
sys 0m0.000s

so 400ms for this version doing 100000

With 'sprintf':

#include <stdio.h>
#include <string.h>

char str[60*1000];

extern char * get_str(void);

int
main(void) {
char * s;
char * ns;
for (int i=0; i<100000; ++i) {
ns = get_str();
s = str;
s += sprintf(s, "%s", ns);
s += sprintf(s, "%s", ns);
s += sprintf(s, "%s", ns);
s += sprintf(s, "%s", ns);
sprintf(s, "%s", ns);
}
puts(str);
return 0;
}

time ./b5c > /dev/null

real 0m0.473s
user 0m0.468s
sys 0m0.000s
BTW: For my tests I used 'get_str', so I renamed yours to 'get_str'
to fit.

> You might be surprised at the results.
>
> (With N=1000000 here, and 100 iterations, gcc-O3 gave me figures of
> 440/2320 msec - sprintf was still several times slower.)

Well, there are various design points. On short strings on my
machine I get similar time as you with 'sprintf' and 2.4s
using 'strcat' + 'strlen'. But on longer strings seem to be
much faster (as I wrote on my machine string handling is via
SSE instructions).

--
Waldek Hebisch

Re: Why does C allow structs to have a tag?

<sf3mm1$4kk$1@dont-email.me>

  copy mid

https://www.novabbs.com/devel/article-flat.php?id=17943&group=comp.lang.c#17943

  copy link   Newsgroups: comp.lang.c
Path: i2pn2.org!i2pn.org!eternal-september.org!reader02.eternal-september.org!.POSTED!not-for-mail
From: david.br...@hesbynett.no (David Brown)
Newsgroups: comp.lang.c
Subject: Re: Why does C allow structs to have a tag?
Date: Thu, 12 Aug 2021 19:44:33 +0200
Organization: A noiseless patient Spider
Lines: 152
Message-ID: <sf3mm1$4kk$1@dont-email.me>
References: <s9iea5$n5c$1@dont-email.me> <seejf8$9ti$1@dont-email.me>
<WowPI.4743$NQ1.1007@fx48.iad> <sembba$oul$1@dont-email.me>
<CrQPI.669$bS5.239@fx21.iad> <seoqf4$pj7$1@dont-email.me>
<87czqnlp2m.fsf@bsb.me.uk> <WFWPI.1865$un2.1665@fx04.iad>
<FiCQI.401$uk4.259@fx20.iad> <poCQI.37363$EF2.25668@fx47.iad>
<VNCQI.5685$Ug5.514@fx24.iad> <seuu75$il3$1@dont-email.me>
<TEEQI.5686$Ug5.143@fx24.iad> <GCQQI.17254$lK.16624@fx41.iad>
<5d8700fd-6ba7-4c72-ae2f-1d4ea91fe823n@googlegroups.com>
<PHRQI.5464$xY.2133@fx05.iad> <sf0re4$v91$1@dont-email.me>
<sf1d0q$iiu$1@dont-email.me> <sf1had$5p9$1@dont-email.me>
<sf2m68$2q5$1@dont-email.me> <sf2vk1$t6o$1@dont-email.me>
<sf3b5u$eou$1@dont-email.me> <sf3ggk$m9i$1@dont-email.me>
Mime-Version: 1.0
Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: 8bit
Injection-Date: Thu, 12 Aug 2021 17:44:33 -0000 (UTC)
Injection-Info: reader02.eternal-september.org; posting-host="87af160eafdf186559d4b8da1e6a6bda";
logging-data="4756"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX1+R9dAOskXAIKE7g5cgt2AKT7tBYeuTAYY="
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:78.0) Gecko/20100101
Thunderbird/78.11.0
Cancel-Lock: sha1:3orrM7UEYQOjEPSSIxN+gyW03DA=
In-Reply-To: <sf3ggk$m9i$1@dont-email.me>
Content-Language: en-GB
 by: David Brown - Thu, 12 Aug 2021 17:44 UTC

On 12/08/2021 17:59, Bart wrote:
> On 12/08/2021 15:28, David Brown wrote:
>> On 12/08/2021 13:10, Bart wrote:
>
>>> That doesn't tell you much about non-optimising compilers, or attempts
>>> to call C functions from other languages, which is MY interest.
>>
>> No one (sane and knowledgable) cares about the speed of code generated
>> by non-optimising compilers, or compilers with the optimisation turned
>> off.
>>
>> No one (sane and knowledgable) who calls library functions from another
>> language cares about the results of a compiler running test code - they
>> care about the /library/, its implementation, and efficiency.
>
> That is just your opinion. Many of us do care about it, since
> unoptimised code can give highly useful trade-offs (like 100 times
> faster build speeds - ask any Rust developer whether they would like a
> 100x faster build just once).

I have no experience of Rust. But I can tell assure you that "gcc -O0"
does not run 100 times faster than "gcc -O2", and is nowhere near as
useful. It is rare for the speed of C compilation - even when optimised
- to be of a significant hinder to professional (or serious hobby) C
developers. I'm sure there are /some/ people out there regularly
recompiling the Linux kernel natively on a Pi 1, but there can't be
many. There are possibly some who mistakenly think compilation without
optimisation is a good way to do a quick check of code quality.
Regardless, how many of those that you think intentionally compile with
optimisations disabled are particularly interested in the run-time speed
of the resulting code?

>
> Any native code non-optimising compiler can still generate code that
> will wipe the floor with any interpreted scripting language.
>

For most (for a very vague, hand-waving and unsubstantiated measurement
of "most") code, run-time speed is not particularly important.

I did not say that people don't run compilers without optimisations. I
said that people who care about the speed of the results don't run
compilers without optimisations.

(Actually, I did miss out a class of programmers who may run compilers
without optimisations, while caring about speed. There are some
commercial toolchains where there are price differences for licenses or
versions with and without optimisations.)

> So there is a place for such implementations.
>
> (I'd also imagine that my non-optimising compilers would generate faster
> code on your machine, than gcc-O3 on mine.)
>

So what?

If I want code to be fast, I enable optimisations. If I want it to be
small, I enable optimisations. If I want static error checking to catch
errors in my code at the earliest opportunity, I enable optimisations.
If I don't care about any of that, then C is highly unlikely to be the
right language for the task. I cannot imagine any circumstance in which
I'd want to disable optimisation during code development.

>> So if you are interested in the performance of strcat and sprintf when
>> used from a different language, look at the library, not the C compiler.
>
> You could just write a benchmark if the results are actually in dispute.
> Just stating an opinion wouldn't be enough for Scott, but then neither
> are hard facts apparently.
>

No one has given any hard facts to counter his personal experience, and
your opinions are not likely to be attributed much weight. (I know /I/
can't write a benchmark to counter his post, because I believe he was
thinking of particular use-cases, and I don't know what they are.)

Nevertheless, my point stands - if you are interested in the speed of
library functions, then concentrate on the library functions, not the
compiler. (That's assuming you know what library you are using, of course.)

>
>>> (With N=1000000 here, and 100 iterations, gcc-O3 gave me figures of
>>> 440/2320 msec - sprintf was still several times slower.)
>>>
>>
>> I haven't claimed that sprintf is faster - I merely gave a possible
>> explanation why it might be faster, for some situations.
>
> You said it's probably faster for short strings. It seems it can be
> faster for much longer ones, but presumably not quoye as long as DFS's.
>

I said sprintf is going to be faster for /longer/ strings, because (in
code sequences like your test code) it avoids the need to continually
re-scan strings to find their length. That is, I think, quite obvious.

(It's always possible that I jumbled my words in a post and wrote the
opposite of what I meant. I'm sure you'll let me know if that was the
case.)

>> But looking at the code generated for your latest change, I notice
>> something vital - gcc (on godbolt) is converting many of the "strcat"
>> calls into "stpcpy" calls.  stpcpy is not a standard C function, but is
>> (AFAICS) in POSIX standards.  It is like strcpy, except it returns a
>> pointer to the end of the combined string - and is thus vastly more
>> efficient in this case.
>
> strcat is a very simple function - at least in spec - and thus could
> lend itself easily to optimisation.
>

Yes.

> I use it extensively from outside of C, but usually in cases that are
> not speed-critical (such as generating diagnostic listings, or
> synthesising command strings for system()).
>
> But I rarely use any *printf functions via FFIs; format strings just
> don't belong outside of C.
>

Format strings of various sorts are used in many languages. But I can
fully understand not wanting C-specific printf and format strings in
other languages.

> For building text files in-memory by concatenating, a method I also use
> all the time, I use streamlined functions of my own.
>
>> That is another reason why
>> blanket statements (whether by you or by Scott) without context about
>> the relative speed of two functions or techniques are usually
>> meaningless.  You have to compare real-world speeds in the situations
>> you are using them.
>
>
> Funny how one remark by Scott that was likely erroneous and misleading
> attracts virtually no comment. But someone TRIES to show that they are
> wrong, and you try to annihilate them.
>

I don't know that Scott's remark was erroneous or misleading - but it
could certainly have helped with some more explanation. (Then we might
be in a position to judge better whether or not it was correct.)

I haven't been trying to "annihilate" you - that's paranoia. I have not
even disagreed with your main point about strcat being faster (in
general) than sprintf - nor has anyone else, I think. But I /have/
disagreed with some of your methods, and tried to explain why and how to
improve on them.

Re: Why does C allow structs to have a tag?

<sf3nki$c30$1@dont-email.me>

  copy mid

https://www.novabbs.com/devel/article-flat.php?id=17944&group=comp.lang.c#17944

  copy link   Newsgroups: comp.lang.c
Path: i2pn2.org!i2pn.org!eternal-september.org!reader02.eternal-september.org!.POSTED!not-for-mail
From: david.br...@hesbynett.no (David Brown)
Newsgroups: comp.lang.c
Subject: Re: Why does C allow structs to have a tag?
Date: Thu, 12 Aug 2021 20:00:49 +0200
Organization: A noiseless patient Spider
Lines: 68
Message-ID: <sf3nki$c30$1@dont-email.me>
References: <s9iea5$n5c$1@dont-email.me> <sembba$oul$1@dont-email.me>
<CrQPI.669$bS5.239@fx21.iad> <seoqf4$pj7$1@dont-email.me>
<87czqnlp2m.fsf@bsb.me.uk> <WFWPI.1865$un2.1665@fx04.iad>
<FiCQI.401$uk4.259@fx20.iad> <poCQI.37363$EF2.25668@fx47.iad>
<VNCQI.5685$Ug5.514@fx24.iad> <seuu75$il3$1@dont-email.me>
<TEEQI.5686$Ug5.143@fx24.iad> <GCQQI.17254$lK.16624@fx41.iad>
<5d8700fd-6ba7-4c72-ae2f-1d4ea91fe823n@googlegroups.com>
<PHRQI.5464$xY.2133@fx05.iad> <sf0re4$v91$1@dont-email.me>
<sf1e9g$14$1@z-news.wcss.wroc.pl> <sf1i29$jdp$1@dont-email.me>
<sf1j2u$6h1$1@dont-email.me> <sf2mnq$69m$1@dont-email.me>
<sf30he$3gc$1@dont-email.me> <sf3c4m$m4h$1@dont-email.me>
<sf3hoa$vto$1@dont-email.me>
Mime-Version: 1.0
Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: 7bit
Injection-Date: Thu, 12 Aug 2021 18:00:50 -0000 (UTC)
Injection-Info: reader02.eternal-september.org; posting-host="87af160eafdf186559d4b8da1e6a6bda";
logging-data="12384"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX19meCsKDbogIncNu5+uL2CqKZVAJK3KdQs="
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:78.0) Gecko/20100101
Thunderbird/78.11.0
Cancel-Lock: sha1:Klm0fMAuznOqz+tuXtyqr4PtNSI=
In-Reply-To: <sf3hoa$vto$1@dont-email.me>
Content-Language: en-GB
 by: David Brown - Thu, 12 Aug 2021 18:00 UTC

On 12/08/2021 18:20, Bart wrote:
> On 12/08/2021 15:44, David Brown wrote:
>> On 12/08/2021 13:26, Bart wrote:
>
>
>> Show me a /realistic/ use-case for combining the same simple string to
>> itself a million times.
>
>
> Show me a use-case for testing vehicles by driving round and round the
> same circular track.

There are plenty, as you well know. Pushing an analogy past its
breaking point does not make you right.

>
> It seems you just don't get benchmarks. Many are necessarily repetitive,
> and need to concentrate on a specific thing that is being tested. And
> all are meaningless.

I did not say benchmarks are not useful - they are, in some cases, when
they can be used to measure something useful. I objected to your
characteristic of your code as "realistic", which it most certainly is not.

>
> I could change my getstr() routine to return a random string of random
> length, but that makes it harder to measure and compare results, and you
> would just find another reason to discredit it.
>

That would change the kind of benchmark, perhaps giving more useful
results (without improving the realism at all). But it is still not
clear what you would be testing or how it relates to speeds and
bottlenecks in /real/ code. If the speed of string concatenation in
real world code (of a particular type) is limited by cache speeds rather
than processor speeds, then the function that gives the fastest results
will be the one that uses fewer memory accesses - not the one that wins
on such limited synthetic benchmarks. At the moment, all you are doing
is benchmarking the speed of your benchmark, which is not relevant to
real programming.

> Here's a challenge for you: some students each present you with an
> opaque implementation of [for example] strcat (but renamed to avoid
> confusion). You need to grade according them according to how efficient
> (ie. how fast) they are on a range of test inputs.
>
> How would you go about testing them? Don't forget you're not allowed to
> use loops, or apply the same inputs more than once.
>

I would want to know under what circumstances the functions are intended
to be used. Otherwise, the question is meaningless.

> How would you distinguish an entry which is fast because of technique,
> from one which is fast because of a clever compiler which can take
> advantage of the specific test context?
>
> What would you think of a compiler smart enough to recognise the
> function as doing what strcat does, and replaces it with the
> highly-optimised built-in strcat; would you consider that a good or bad
> thing, from the point of view of doing your job?

Those are all good questions to consider before deciding how the
implementations should be judged.

Usually, I'd pick the one that is most clearly correctly implemented.
Black box implementations get zero marks on that score, regardless of
whether they passed or failed any tests.

Pages:12345678910111213141516
server_pubkey.txt

rocksolid light 0.9.8
clearnet tor