4 ms·
I am pretty convinced by the argument of this article. but, this looks to good to be true. Are there some drawbacks I can not see ? Why nobody has thought about
by reacweb 11y ago
I am pretty convinced by the argument of this article. but, this looks to good to be true. Are there some drawbacks I can not see ? Why nobody has thought about this simple api ?
- ktRolster 11y agoOf all the problems with C strings, the one mentioned in the article (inefficient strcat() function) is really small. I think unicode support would be much more important, but not everyone agrees (for example, on embedded devices unicode support can be dead-weight). And adding to C without consensus leads to lousy decisions.
- reacweb 11y agoI have already noticed some performance issue with strncpy (and big destination buffers) vs strlcpy. The two functions introduced in the article have the good complexity and seem to be more handy than usual api.
- ktRolster 11y agoIf you need to copy big strings, memcpy is worth checking out, too.
- int0x80 11y agoIMO it is usefull to have the "return result paradigm". You can do things like: bar(foo(x, y)) and chain function results. Notice how this applies to strcpy: char *heap_ptr, *stack_ptr; ... fn_needs_heap_ptr(strcpy(heap_ptr, stack_ptr)); Another example (dma address space != buf a.s): char *dma_ptr, *buf; ... fn_needs_dma_ptr(strcpy(dma_ptr, buf)) ... IOW, foo(strcpy(dst, src)) is VERY different than strcpy(dst, src); foo(src);
- huhtenberg 11y agoBecause the performance hit of extraneous strlen() calls is generally negligible. This in turn is because strlen() maps to "repne scasb" assembly instructions, which run in 4 cycles per byte + 8 cycles of fixed cost. That's cheap as dirt. You will indeed have a problem if you strcat() excessively, but then it will be a marginal case, so you will optimize for it in your own code rather than dragging it into the standard.
- vardump 11y ago> which run in 4 cycles per byte + 8 cycles of fixed cost. That's cheap as dirt. Cheap? 12 precious clock cycles is enough for up to 384 floating point operations (FMA). Not sure how fast or slow rep sca/mov is these days. Regardless, strlen that is not scanning at least 4 bytes per clock is hopelessly slow. I think you can do at least about ~16 bytes per clock. Anyways, the problem with strlen is unnecessary extra (potentially mispredicted) branches and memory accesses. I have seen enough cases where strlen has dominated cost in the profile. Of course this depends entirely what you are doing, there are plenty of workloads where strlen just doesn't occur.
- asgfoi 11y agoIsn't a modern strlen optimized into vector operations if possible anyway?
- vardump 11y agoYes. Though you still pay for the memory/branch prediction stalls.
- giggi89 11y agoso...are we trying to micro-optimize the standard library? There will be bottlenecks narrower (is that the right term?) than string operation in any project not dealing exclusively with strings. In the latter case, rolling your own string utilities may make sense
- vardump 11y agoOf course you shouldn't optimize unless it's the biggest bottleneck and more performance (or battery life) is desired. C string operations might have been elegant 40 years ago, but nowadays they're like rerouting a 747 to check if office lights are on. Strlen is doing a lot of work for little benefit. It does slow and power hungry memory accesses. Because it's scanning for terminating 0x00 byte, it needs to contain a branch -- and loop terminating branch must be a costly mis-predicted one. C printf and friends are even more insane. It scans "bytecode" instructions from a string and does dynamic formatting. You can do format options like this: printf("% 0#*.*f\n", 15, 5, 1.234); Or say print five chars of an unterminated string, left padded to total length of 10: printf("%10.5s\n", unterminated_str); It won't (at least it shouldn't) crash even if 6th character is on an unreadable memory page.
- keeperofdakeys 11y agoAll string manipulation code in C deals with trailing NULL bytes, so if you try doing something different, you may get issues when you try to link to other code. It's not a great system, but good C programmers should know the shortfalls. As an example of the alternate approach, the Rust language uses (ptr, size) to represent all arrays (called slices) and strings internally. This seems like a much better method, allowing you to reference substrings without allocating a buffer, and perform out-of-bounds checking at runtime.