0

I have noticed that in my implementation of printf for C. One buffer of 1024 bytes is allocated and used for all subsequent calls and not explicitly freed (with the quoted justification being that the Linux kernel will do so upon program termination).

I have read about buffered I/O; however, I do not quite understand why this buffer is reused instead of allocating a buffer of necessary size for each call. I have considered the following reasons:

  • reduce number of system calls
  • malloc may take uncertain amount of time or have variable results
  • the amount of space necessary may not be available (unlikely on my system)

I do not quite understand the motivation. Can anyone provide a clear cut reason? Obviously this is simply speculation, unless the person who wrote the source for printf were to see this question.

  • Any space that is repeatedly allocated must be deallocated explicitly — you can't leave it to process end — otherwise you have a memory leak. So #3 is a non-issue. However, allocation is a relatively slow process, and the primary purpose for C is low-level proramming, where speed of execution is paramount; so your #1 and #2 should be pretty close to the mark. – Amadan Mar 31 '23 at 00:29
  • @Amadan worrying about the speed of memory allocation is silly in the context of how long printf usually takes. – Mark Ransom Mar 31 '23 at 00:31
  • 2
    @MarkRansom I don't think worrying about speed in any function of what is probably the most used runtime in the world is silly. Sure, `printf` will usually depend on IO and thus block, but CPU can do other things in the meantime, so saying "`printf` is slow anyway we might as well not optimise it" does not make much sense to me. – Amadan Mar 31 '23 at 00:51
  • 1
    @MarkRansom: Opting to waste time because a lot of time is already bring expended would be a bad decision. – Eric Postpischil Mar 31 '23 at 00:53
  • Are you asking about a buffer specific to `printf`, or the ordinary output buffer associated with `stdout`? Can you provide any kind of a link or reference to the code you're asking about? – Steve Summit Mar 31 '23 at 01:00
  • *not explicitly freed (with the quoted justification being that the Linux kernel will do so upon program termination)* That is certainly an adequate justification. See [Should I free memory before exit?](https://stackoverflow.com/questions/36584062) and [What REALLY happens when you don't free after malloc before program termination?](https://stackoverflow.com/questions/654754) – Steve Summit Mar 31 '23 at 01:02
  • @Amadan I'm not even talking about blocking on I/O. By its nature printf is slow because the format must be interpreted and the data converted. – Mark Ransom Mar 31 '23 at 01:02
  • @EricPostpischil I'm not suggesting to waste time unnecessarily. I'm just saying *don't worry about it*. Knuth's famous quote comes to mind. – Mark Ransom Mar 31 '23 at 01:05
  • 1
    @MarkRansom I'm a huge fan of that quote, but as others have said here, `printf` is probably the most-called function in all of C-dom. If there's a hardworking function that's worth optimizing the hell out of, and for which that optimization is **not** "premature", it's certainly `printf`! – Steve Summit Mar 31 '23 at 01:06
  • @MarkRansom For an average programmer doing average programming, sure. But specifically for anything in libc, it is not premature. It's like "don't worry if your HTML is indented by 2 or 4 spaces" is in general a sound policy; but Google Search HTML source is optimised down to the last byte. OP is not asking whether they should worry about allocation time, but whether _specifically whoever wrote and maintained `printf` did_. – Amadan Mar 31 '23 at 01:09
  • @user9329423 Whenever you're using a resource temporarily, but are temporarily done with it — whether it's a tool you borrowed from a friend, or a car you rented, or some memory you got from `malloc` — you always have a decision. If you might need it again later, is it worth returning it and then having to go through the trouble of borrowing it again, or should you just hang onto it? Either guess might be wrong and therefore costly. But given how often `printf` is called, by virtually every C program in existence, I'd say the authors made the right choice! Is another call likely? *Yes!* – Steve Summit Mar 31 '23 at 01:09
  • @SteveSummit I'm not saying that printf isn't worth optimizing, although it might not be - anything time sensitive that relies on it is in trouble already. Rather I'm saying that any savings you could make in allocation, even taking it to zero as apparently was done here, would be unlikely to make any measurable difference to the final outcome. – Mark Ransom Mar 31 '23 at 01:20

1 Answers1

0

I am interpreting your question broadly as "what is the benefit of reusing memory buffers" instead of performing dynamic memory allocation every time memory is used. There are two good technical reasons for doing this:

  • Memory allocation can be expensive operation (compared to pure compute), if the memory allocator actually needs to ask for more memory from the system.
  • Reusing the same memory can improve CPU cache performance, because there's a greater chance that the memory will already be cached.

If you want to know the specific reason for printf to do this and the specific tradeoffs considered, I would recommend emailing the authors.

merlin2011
  • 71,677
  • 44
  • 195
  • 329