[OPEN-ILS-DEV] C nits: utils.c (Part 2)
Bill Erickson
billserickson at gmail.com
Fri Mar 23 09:02:09 EDT 2007
Scott,
This is great, thanks. The growing_buffer is used widely, as you say, so
starting there is a good place. Also, a little premature optimization won't
hurt with such frequently accessed code. I won't bother going through each
point individually, because I think it's all generally good advice.
A lot of the code you're looking at is mine, and you can probably tell that
I was not "raised" as a C programmer, though I'm quite fond of the language,
so your pointers on style in addition to optimization are greatly
appreciated.
I'll be returning to "C nits: utils.c (Part 1)" as time permits.
Thanks again,
-bill
**
On 3/22/07, Scott McKellar <mck9 at swbell.net> wrote:
>
> Gentlemen:
>
> I have turned my attention to the growing_buffer routines. I believe
> I see some opportunities for improvement, starting with buffer_add().
>
> Some of my suggestions may fall into the category of premature
> optimization. However I suspect that the growing_buffer routines are
> so widely used that even a small performance tweak might add up to
> something significant.
>
> First: the second parameter absolutely should be a pointer to const
> char. Without the const qualifier in the signature, the compiler will
> not let you pass a const pointer, and there's no reason to restrict
> yourself that way.
>
> A pedantic point: data_len and total_len should be declared as size_t
> rather than int. That's what strlen() returns, and neither will ever
> have a negative value, so they might as well be unsigned.
>
> For that matter the size and n_used members of growing_buffer should
> probably be size_t as well, and buffer_add() should return a size_t.
> These are the sorts of things for which size_t was intended.
>
> Granted, it's unlikely that leaving them as ints will ever do any
> harm. It's a stylistic point upon which reasonable people may
> disagree.
>
> A second pedantic point: In your error message you format
> BUFFER_MAX_SIZE as an int, with the "%d" format. I'm not sure what
> type the compiler applies to an integer literal, such as
> BUFFER_MAX_SIZE expands to. Probably it's an int unless it's too
> big to be an int.
>
> In any case there are systems where the value of BUFFER_MAX_SIZE won't
> fit into an int. Probably none of them would ever run Open-ILS.
> However I can imagine someone trying to port fragments of your
> code to MS-DOS, for example. Of course, he or she would probably
> have to change the value of BUFFER_MAX_SIZE anyway.
>
> In any case, the pedantically correct thing to do is to use the "%ld"
> format, and cast BUFFER_MAX_SIZE to a long. Alternatively you could
> append an "L" to the definition of this macro. You could also use
> the "%lu" format and turn BUFFER_MAX_SIZE to an unsigned long.
>
> When you issue this error message, you also destroy the growing_buffer
> and its contents. I don't understand why you do that. Why throw
> away something you already have? I suppose the idea is to enforce
> discipline by making a coredump likely if the calling code doesn't
> scrupulously check the return value. However I suspect that this
> error happens rarely enough that the enforcement is not very
> effective.
>
> Now for the good stuff.
>
> When you expand the buffer, consider using realloc() instead of
> malloc(). If realloc() can expand the buffer in place instead of
> allocating a completely new one, then you can avoid doing the
> strcpy() and the free(). You may also reduce the fragmentation of
> memory.
>
> Whether this measure helps will depend on how often realloc() can
> expand the buffer in place. I have no way to guess how often that
> happens. It probably depends on the application.
>
> You would likely want to wrap realloc() in a safe_realloc function, or
> an OSRF_REALLOC macro.
>
> Finally: when you append the string to the buffer, use strcpy()
> instead of strcat():
>
> strcpy( gb->buf + gb->n_used, data );
>
> Rationale: strcat() has to spend CPU cycles finding the end of the
> original string. But you already know where the end of the string
> is. You might as well put that information to good use.
>
> Scott McKellar
> mck9 at swbell.net/mck9/aargh/
>
>
--
Bill Erickson
PINES Systems Developer
Georgia Public Library Service
billserickson at gmail.com
http://open-ils.org
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://list.georgialibraries.org/pipermail/open-ils-dev/attachments/20070323/340ecfc1/attachment-0001.html
More information about the Open-ils-dev
mailing list