Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

> There are tricks that let them do this 8 bytes at a time (on AMD64, 4 bytes on x86)

It's actually 16 bytes at a time on any machine that supports SSE (maybe 32 bytes soon with AVX).

> Different abstractions, such as Python's strings, can very often do this comparison with almost no memory access:

Sure, different abstractions have different trade-offs. All of these abstraction possibilities are available to C. strlen() isn't "the C approach," it's just the most common one. Any C application where comparison of long almost-identical strings is important will surely use techniques similar to what Python does. On the other hand, the reverse is not true: Python does not have access to all the same optimizations that a C programmer could draw upon to do string processing.



I was mostly replying to your assertion that "that's not even remotely how strcmp is implemented", which, for most definition of "even remotely", is false.

> All of these abstraction possibilities are available to C

That's a tautology at best, and meaningless at worst. The way strcmp() is implemented, which we discussed above, is not actually available in C.

> Any C application where comparison of long almost-identical strings is important will surely use techniques similar to what Python does.

And similarly, any Python application that requires (insert some uncommon requirement ..) can do what C can with the same kind of help that strcmp() gets - by delegating to the layer that does it best.

> Python does not have access to all the same optimizations that a C programmer could draw upon to do string processing.

Pure python is more limited than C, true. But specific Python implementations (RPython, PyPy, IronPython) might have better access to some optimizations than specific C implementations.

And there's always the aspect of "what's theoretically possible" and "what happens in practice". The fact that PyPy will dynamically switch from 32-bit to 64-bit to unbounded-long-integer might make a real difference on a 32-bit machine where the code might occasionally require 2048 bits, but overwhelmingly requires just 32 bits.

It is possible to construct pathological cases where there are e.g. pow(2,128) possible type combinations within a function, the exact combination is only known from the data (but is consistent for an entire run) - in which case, PyPy will essentially compile the right program to machine code, whereas you cannot do AOT because of the number of combinations; which means a C program will essentially be an interpreter based on those types.

But I don't care about theoretically constructed pathologies. In practice, especially with time-to-implement constraints, it is not true that a C programmer has all the tools at their disposal that higher level languages have.


> I was mostly replying to your assertion that "that's not even remotely how strcmp is implemented", which, for most definition of "even remotely", is false.

eglibc's SSE2 implementation of strcmp is just over 5k of machine code, whereas the simple implementation compiles to 56 bytes on x64-64. That was my definition of "not even remotely." I did not mean to imply that it was a fundamentally different algorithm, only that it was a far more sophisticated and optimized implementation of the same algorithm. My apologies if this was unclear or appeared overstated.

> That's a tautology at best, and meaningless at worst.

By "these abstraction possibilities" I meant the ones you mentioned, which is true.

> And similarly, any Python application that requires (insert some uncommon requirement ..) can do what C can with the same kind of help that strcmp() gets - by delegating to the layer that does it best.

That's great and I fully support that. What I am arguing against is high-level language cheerleading that discounts the importance of C (or assembly for that matter). Since you mention PyPy, I have to say that their PR is some of the worst in this regard; some of their "faster than C" claims are actively misleading, like this one that benchmarks some generated string formatting code against sprintf() (which re-parses the format string every time): http://morepypy.blogspot.com/2011/08/pypy-is-faster-than-c-a...


> > There are tricks that let them do this 8 bytes at a time (on AMD64, 4 bytes on x86)

> It's actually 16 bytes at a time on any machine that supports SSE (maybe 32 bytes soon with AVX).

Is there a sequence of fewer than 16 instructions to spot a NUL byte inside the 16 byte block?


> Is there a sequence of fewer than 16 instructions to spot a NUL byte inside the 16 byte block?

Yes:

    pxor  %xmm1, %xmm1
    pcmpeqb (mem), %xmm1  // Do 16 byte-wise compares
    pmovmskb %xmm1, %eax  // Move results into the low 16 bits
    test %eax, %eax
    jnz saw_null


Very cool.




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

Search: