public inbox for cygwin-patches@cygwin.com
 help / color / mirror / Atom feed
* avoid calling strlen() twice in readlink()
@ 2012-03-08 13:37 Václav Zeman
  2012-03-08 14:57 ` Corinna Vinschen
  2012-03-08 15:29 ` Eric Blake
  0 siblings, 2 replies; 6+ messages in thread
From: Václav Zeman @ 2012-03-08 13:37 UTC (permalink / raw)
  To: cygwin-patches

[-- Attachment #1: Type: text/plain, Size: 215 bytes --]

Hi.

Here is a tiny patch to avoid calling strlen() twice in readlink().

ChangeLog:

2012-03-08  Václav Zeman  <vhaisman@gmail.com>

        * path.cc (readlink): Avoid calling strlen() twice.

-- 
VZ

[-- Attachment #2: path.cc.diff.txt --]
[-- Type: text/plain, Size: 437 bytes --]

--- path.cc	2012-03-07 18:10:44.000000000 +0100
+++ path.cc	2012-03-08 13:28:28.468266800 +0100
@@ -2782,7 +2783,8 @@ readlink (const char *path, char *buf, s
       return -1;
     }
 
-  ssize_t len = min (buflen, strlen (pathbuf.get_win32 ()));
+  size_t pathbuf_len = strlen (pathbuf.get_win32 ());
+  size_t len = MIN (buflen, pathbuf_len);
   memcpy (buf, pathbuf.get_win32 (), len);
 
   /* errno set by symlink.check if error */

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: avoid calling strlen() twice in readlink()
  2012-03-08 13:37 avoid calling strlen() twice in readlink() Václav Zeman
@ 2012-03-08 14:57 ` Corinna Vinschen
  2012-03-08 15:29 ` Eric Blake
  1 sibling, 0 replies; 6+ messages in thread
From: Corinna Vinschen @ 2012-03-08 14:57 UTC (permalink / raw)
  To: cygwin-patches

On Mar  8 14:37, Václav Zeman wrote:
> Hi.
> 
> Here is a tiny patch to avoid calling strlen() twice in readlink().
> 
> ChangeLog:
> 
> 2012-03-08  Václav Zeman  <...>
> 
>         * path.cc (readlink): Avoid calling strlen() twice.

Thanks, applied.


Corinna

-- 
Corinna Vinschen                  Please, send mails regarding Cygwin to
Cygwin Project Co-Leader          cygwin AT cygwin DOT com
Red Hat

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: avoid calling strlen() twice in readlink()
  2012-03-08 13:37 avoid calling strlen() twice in readlink() Václav Zeman
  2012-03-08 14:57 ` Corinna Vinschen
@ 2012-03-08 15:29 ` Eric Blake
  2012-03-08 15:56   ` Corinna Vinschen
  1 sibling, 1 reply; 6+ messages in thread
From: Eric Blake @ 2012-03-08 15:29 UTC (permalink / raw)
  To: cygwin-patches

[-- Attachment #1: Type: text/plain, Size: 543 bytes --]

On 03/08/2012 06:37 AM, Václav Zeman wrote:
> Hi.
> 
> Here is a tiny patch to avoid calling strlen() twice in readlink().
> 

>  
> -  ssize_t len = min (buflen, strlen (pathbuf.get_win32 ()));
> +  size_t pathbuf_len = strlen (pathbuf.get_win32 ());
> +  size_t len = MIN (buflen, pathbuf_len);
>    memcpy (buf, pathbuf.get_win32 (), len);

For that matter, is calling pathbuf.get_win32() twice worth factoring out?

-- 
Eric Blake   eblake@redhat.com    +1-919-301-3266
Libvirt virtualization library http://libvirt.org


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 620 bytes --]

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: avoid calling strlen() twice in readlink()
  2012-03-08 15:29 ` Eric Blake
@ 2012-03-08 15:56   ` Corinna Vinschen
  2012-03-08 18:48     ` Christian Franke
  0 siblings, 1 reply; 6+ messages in thread
From: Corinna Vinschen @ 2012-03-08 15:56 UTC (permalink / raw)
  To: cygwin-patches

On Mar  8 08:29, Eric Blake wrote:
> On 03/08/2012 06:37 AM, Václav Zeman wrote:
> > Hi.
> > 
> > Here is a tiny patch to avoid calling strlen() twice in readlink().
> > 
> 
> >  
> > -  ssize_t len = min (buflen, strlen (pathbuf.get_win32 ()));
> > +  size_t pathbuf_len = strlen (pathbuf.get_win32 ());
> > +  size_t len = MIN (buflen, pathbuf_len);
> >    memcpy (buf, pathbuf.get_win32 (), len);
> 
> For that matter, is calling pathbuf.get_win32() twice worth factoring out?

It's just a const char *pointer, and it's an inline method.  I'm pretty
sure the compiler will optimize this just fine.


Corinna

-- 
Corinna Vinschen                  Please, send mails regarding Cygwin to
Cygwin Project Co-Leader          cygwin AT cygwin DOT com
Red Hat

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: avoid calling strlen() twice in readlink()
  2012-03-08 15:56   ` Corinna Vinschen
@ 2012-03-08 18:48     ` Christian Franke
  2012-03-09 11:35       ` Václav Zeman
  0 siblings, 1 reply; 6+ messages in thread
From: Christian Franke @ 2012-03-08 18:48 UTC (permalink / raw)
  To: cygwin-patches

Corinna Vinschen wrote:
> On Mar  8 08:29, Eric Blake wrote:
>> On 03/08/2012 06:37 AM, Václav Zeman wrote:
>>> Hi.
>>>
>>> Here is a tiny patch to avoid calling strlen() twice in readlink().
>>>
>>>
>>> -  ssize_t len = min (buflen, strlen (pathbuf.get_win32 ()));
>>> +  size_t pathbuf_len = strlen (pathbuf.get_win32 ());
>>> +  size_t len = MIN (buflen, pathbuf_len);
>>>     memcpy (buf, pathbuf.get_win32 (), len);
>> For that matter, is calling pathbuf.get_win32() twice worth factoring out?
> It's just a const char *pointer, and it's an inline method.  I'm pretty
> sure the compiler will optimize this just fine.
>
>

Yes - and it does ever more:
strlen() is one of the compiler builtins declared with a const attribute 
internally. Then gcc optimizes duplicate calls away.

Testcase:

$ cat opt.cc
#include <string.h>

class X {
   const char * p;
   public:
     X();
     const char * get() { return p; }
};

int f(X & x)
{
   int i = 0;
   i += strlen(x.get());
   i += strlen(x.get());
   i += strlen(x.get());
   i += strlen(x.get());
   i += strlen(x.get());
   return i;
}

int g(X & x)
{
   return 5 * strlen(x.get());
}


$ gcc -S -O2 -fomit-frame-pointer opt.cc

$ cat opt.s | c++filt
...
f(X&):
         subl    $28, %esp
         movl    32(%esp), %eax
         movl    (%eax), %eax
         movl    %eax, (%esp)
         call    _strlen
         addl    $28, %esp
         leal    (%eax,%eax,4), %eax
         ret
...
g(X&):
         subl    $28, %esp
         movl    32(%esp), %eax
         movl    (%eax), %eax
         movl    %eax, (%esp)
         call    _strlen
         addl    $28, %esp
         leal    (%eax,%eax,4), %eax
         ret

(interesting: With -O1 it uses an inline version of strlen, with 
-O2,3,... it doesn't)


So this patch probably had no effect at all, sorry :-)

Christian

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: avoid calling strlen() twice in readlink()
  2012-03-08 18:48     ` Christian Franke
@ 2012-03-09 11:35       ` Václav Zeman
  0 siblings, 0 replies; 6+ messages in thread
From: Václav Zeman @ 2012-03-09 11:35 UTC (permalink / raw)
  To: cygwin-patches

On 8 March 2012 19:48, Christian Franke <Christian.Franke@t-online.de> wrote:
> Corinna Vinschen wrote:
>>
>> On Mar  8 08:29, Eric Blake wrote:
>>>
>>> On 03/08/2012 06:37 AM, Václav Zeman wrote:
>>>>
>>>> Hi.
>>>>
>>>> Here is a tiny patch to avoid calling strlen() twice in readlink().
>>>>
>>>>
>>>> -  ssize_t len = min (buflen, strlen (pathbuf.get_win32 ()));
>>>> +  size_t pathbuf_len = strlen (pathbuf.get_win32 ());
>>>> +  size_t len = MIN (buflen, pathbuf_len);
>>>>    memcpy (buf, pathbuf.get_win32 (), len);
>>>
>>> For that matter, is calling pathbuf.get_win32() twice worth factoring
>>> out?
>>
>> It's just a const char *pointer, and it's an inline method.  I'm pretty
>> sure the compiler will optimize this just fine.
>>
>>
>
> Yes - and it does ever more:
> strlen() is one of the compiler builtins declared with a const attribute
> internally. Then gcc optimizes duplicate calls away.
>
> Testcase:
>
> $ cat opt.cc
> #include <string.h>
>
> class X {
>  const char * p;
>  public:
>    X();
>    const char * get() { return p; }
> };
>
> int f(X & x)
> {
>  int i = 0;
>  i += strlen(x.get());
>  i += strlen(x.get());
>  i += strlen(x.get());
>  i += strlen(x.get());
>  i += strlen(x.get());
>  return i;
> }
>
> int g(X & x)
> {
>  return 5 * strlen(x.get());
> }
>
>
> $ gcc -S -O2 -fomit-frame-pointer opt.cc
>
> $ cat opt.s | c++filt
> ...
> f(X&):
>        subl    $28, %esp
>        movl    32(%esp), %eax
>        movl    (%eax), %eax
>        movl    %eax, (%esp)
>        call    _strlen
>        addl    $28, %esp
>        leal    (%eax,%eax,4), %eax
>        ret
> ...
> g(X&):
>        subl    $28, %esp
>        movl    32(%esp), %eax
>        movl    (%eax), %eax
>        movl    %eax, (%esp)
>        call    _strlen
>        addl    $28, %esp
>        leal    (%eax,%eax,4), %eax
>        ret
>
> (interesting: With -O1 it uses an inline version of strlen, with -O2,3,...
> it doesn't)
>
>
> So this patch probably had no effect at all, sorry :-)
Heh, no problem. I really did not know GCC could do that these days.
The benefit seemed too obvious to let it pass :)

-- 
VZ

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2012-03-09 11:35 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-03-08 13:37 avoid calling strlen() twice in readlink() Václav Zeman
2012-03-08 14:57 ` Corinna Vinschen
2012-03-08 15:29 ` Eric Blake
2012-03-08 15:56   ` Corinna Vinschen
2012-03-08 18:48     ` Christian Franke
2012-03-09 11:35       ` Václav Zeman

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).