3 ms·
> And you've just made it impossible for the users of your StringBuilder to pass it around by-value. Every instance has to be malloc'ed by your library, even th
by _gabe_ 3y ago
> And you've just made it impossible for the users of your StringBuilder to pass it around by-value. Every instance has to be malloc'ed by your library, even though it's just a tiny, word-sized struct. Awesome! And each access needs to go through an additional pointer indirection.
...and?
I'm guessing the implication here is that you'll trash performance by doing this. How can you assume that? The thing about optimizing code is, you don't know where your hot paths are until you profile your code. And, the one thing experience has taught me, my intuitions about what the hot spots will be rarely match reality. There's nothing wrong with that, complex systems are complex, and we have incredible profiling tools to eat through that complexity and highlight the hot spots for us.
Now, I know you'll probably go on about a death by a thousand cuts etc. The thing is, well-crafted modules typically don't encapsulate on a fine-grained level. You usually have larger systems that hide details. These systems are usually used a fraction of the time the rest of your program is. So the indirections end up usually being a very insignificant cost to the overall program.
And if you are coding in such a way that copying a string builder by value and/or the indirection imposed by encapsulating that information is a bottleneck, I highly doubt that "fixing" this by copying by value and/or removing the indirection will suddenly make your entire program performant.
> It makes me think that although some of them might be excellent programmers, they make for terrible software engineers.
You haven't actually highlighted any issues here and then go on to finish your argument with an ad hominem. Instead of attacking the competence of C programmers, you should illustrate the actual real world impact that this design philosophy results in. I know plenty of really slow Java libraries, and plenty of really fast C libraries that use this method of encapsulation. So if your argument is that using this method trashes performance, it's a poor argument that doesn't have many real world examples (unless you know of some off the top of your head).
- adwn 3y ago> The thing about optimizing code is, you don't know where your hot paths are until you profile your code. Absolutely! So, you profile your program, and it turns out that 95% of the runtime is caused by malloc/free in tight loops, which you can't get rid of, because they're hidden behind an API which had to choose between encapsulation and efficiency. > And if you are coding in such a way that copying a string builder by value and/or the indirection imposed by encapsulating that information is a bottleneck [...] You don't seem to realize that the StringBuilder was just an example to illustrate this style of encapsulation? Oftentimes you want to encapsulate actual "value structs", where it is sensible to create millions of them in an array. In C, you're forced to choose between following good software engineering practices (=> encapsulation) and getting good performance.
- _gabe_ 3y ago> So, you profile your program, and it turns out that 95% of the runtime is caused by malloc/free in tight loops, which you can't get rid of, because they're hidden behind an API which had to choose between encapsulation and efficiency. I have literally never run into a library that was written so badly that using the library encouraged you to use the API to create millions of small objects. That's what I'm saying. Sure, this can happen, but in reality I've never seen it. Can you show me where this hypothetical scenario is occurring and trashing people's performance? We probably want to avoid using those libraries. Instead, I usually see encapsulation used like it is in GLFW, or libcurl, or stbi. The encapsulation covers systems and not tiny objects, which encourages the user of the library to not make API calls millions of times or construct millions of tiny objects. > You don't seem to realize that the StringBuilder was just an example to illustrate this style of encapsulation? Oftentimes you want to encapsulate actual "value structs", where it is sensible to create millions of them in an array. I did realize this. Encapsulation is typically useful on larger systems. Once you get to the point of millions of objects, you usually have a larger system managing those millions of objects. And ideally, those millions of objects should be POD. If they're POD, encapsulating the data makes no sense at that point, because it makes more sense to encapsulate whatever is managing that data. > In C, you're forced to choose between following good software engineering practices (=> encapsulation) and getting good performance. This is a false dichotomy. There are plenty of large C projects that follow good software engineering practices (which is entirely subjective, what is "good"?). Look at any OS kernel, or the libraries I mentioned above. So, once again, I'm curious if you know of any C libraries (ab)using encapsulation in the hypothetical scenario you've laid out. If there aren't any libraries that do this, then this is a non-issue and attacking the competence of C developers is entirely unwarranted since you've built up a strawman that doesn't exist in reality.
- skinner927 3y agoWhat’s POD? I’m having trouble searching the term.
- _gabe_ 3y ago