Hacker News new | past | comments | ask | show | jobs | submit login

I'd say the case of C strings is more a case of a bad abstraction C has (at least historically), rather than lack of one. But the things that expect them are just the standard library (which doesn't have many useful general-purpose things anyway), so you can write your strings as a pair/struct of char*+length or whatever else you may want just fine.

Small string optimizations, while nice (and probably do average out to being beneficial), aren't always needed, and the extra generated code for handling both cases could make it not worth it if you've got a fast allocator, and can even make some operations just outright slower. (and if your code doesn't actually have strings anywhere near hot loops, all you get is a larger binary). File paths, for example, are often large enough to not fit the small case, but still small enough where even the check for whether it is small can be a couple percent of allocation/freeing.

Being error-prone, though, is something that I can agree with. That's the cost of doing things manually.

(I'd also like to note that malloc/free are a much more important case of a bad abstraction - they have quite a bit of overhead for being able to handle various lengths & multithreading, while a big portion of allocations is on the same (often, only) thread with a constant size, and said size being known at free-time, which is a lot more trivial to handle; not even talking about the cost of calling a non-inlined function spilling things to the stack)




Well the reason this one may be a good example is that you couldn’t do this optimization in C even if you wanted to. You would have to call a function at every use-site to handle your “abstraction”. And the same thing applies in other cases.

Also, I’m not sure the added conditional branch will increase the binary too much, and the reason it is inside the c++ stdlib is that it was likely measured and proved beneficial.

But I do agree that maybe your allocation example is a better one, though the solution to that is perhaps a full GC, which does have a few tradeoffs (which are worthy to take more often than not).


Right; making abstractions in C when you really know you should can be messy, but still possible (not with the same syntax, but I personally like the fact that a[b] is 100% guaranteed to be, at most, a single load; similarly for all operations other than function calls; makes it easier to reason about performance at a glance).

Recommending a GC is hard for me though; over your system malloc/free, maybe, but alternative allocators can be very fast, without the drawbacks of pauses (or slower execution as a result from a non-pausing GC).




Consider applying for YC's Spring batch! Applications are open till Feb 11.

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: