Live data from Hacker News

Rust is now overall faster than C in benchmarks

benchmarksgame-team.pages.debian.net

141–150 of 445 posts

Re: Rust is now overall faster than C in benchmarks

#141
I am not sure I can buy such a comparison. Someone smarter than me already argued about test implementations. Someone else also put compilers and interpreters into prospective. Of course language expressiveness can gauge in but, IMHO, comparing the same sort algorithm or the same hash table implementation (or n-queens algo) could make much more sense especially with comparable compilers.

If Rust implementation is father than C's, kudos goes to the compiler, not to the language

Re: Rust is now overall faster than C in benchmarks

#142
post #76

Looking at the reverse-complement code, it appears that the Rust and C implementations are using different algorithms: https://benchmarksgame-team.pages.debian.net/benchmarksgame/... https://benchmarksgame-team.pages.debian.net/benchmarksgame/... On a quick inspection: - The Rust code is about twice as long. - The Rust code has CPU feature detection and SSE intrinsics, while the C code is more idiomatic. - The lookup…

I recall an anecdote about how Haskell actually outperformed C on various tree benchmarks because it was using a better implementation. At some point, the C programmers got fed up with the airs of superiority from Haskell programmers, ported the Haskell implementation, and reclaimed their position. I wouldn't be surprised if there's something similar happening here.

> I wouldn't be surprised if there's something similar happening here.

In this case it seems like benchmark code is allowed to use intrinsics, which can degenerate into a situation where a benchmark in language X is more "glorified x86 Assembly code" than actual code in language X.

This is not very useful for comparing languages IMO. Especially since all of Rust, C, C++ can use this strategy and become almost identical in both code and performance.

Re: Rust is now overall faster than C in benchmarks

#143
post #109

Earlier quoted context omitted.

> C compilers have to assume that pointers to memory locations can overlap, unless you mark them __restrict... What I don't fully understand is: "GCC has the option -fstrict-aliasing which enables aliasing optimizations globally and expects you to ensure that nothing gets illegally aliased. This optimization is enabled for -O2 and -O3 I believe." (source: https://stackoverflow.com/a/7298596 ) Doesn't this mean that C…

restrict and strict aliasing have to do with the same general concept, but aren't the same. They both have to do with allowing the compiler to optimize around assuming that writes to one pointer won't be visible while reading from another. As a concrete example, can the following branches be merged? void foo(/*restrict*/ bool* x, int* y) { if (*x) { printf("foo\n"); *y = 0; } if (*x) { printf("bar\n"); } } Enabling s…

OK thanks, indeed Clang is able to generate better assembly using __restrict__. And -O3 generates the same assembly as -O3 -fstrict-aliasing (which is not as good as __restrict__).

I wish there was a C/C++ compiler flag for treating all pointers as __restrict__. However I guess that C/C++ standard libraries wouldn't work with this compiler option (and therefore this compiler option wouldn't be useful in practice).

Re: Rust is now overall faster than C in benchmarks

#144
post #104

Earlier quoted context omitted.

Also lack of generics can make it slow, e.g. qsort() requires a function call for each comparison. So C++'s std::sort() can be significantly faster on an array of integers.

It's more to do with the fact that std::sort's definition is visible to the compiler and qsort() is not. Put qsort() code in stdlib.h, make it static and write a static intcmp() and you'll see the compiler inline that no problem.

[deleted]

Re: Rust is now overall faster than C in benchmarks

#145
post #139

Earlier quoted context omitted.

I benchmarked it several times in the past and couldn't replicate std::sort being faster (GCC with high optimization settings). Anyway both are slow. If you need fast sort you need an implementation without any function calls (no recursive calls) and both the pivot choice and the chunk size at which insert sort kicks in optimized to your data and hardware. My experience is that you can beat built in sort by 2x to 3x.

How would you perform this optimization? If it’s the same data getting sorted, why not put it in an ordered data structure?

Andrei Alexanrescu has a talk on doing this - he calls them metaparameters e.g. where a hybrid sort chooses to change algorithm.

One library I have exploits the fact that D templates are embarrassingly better than C++'s, so you can actually benchmark a template against it's parameters in a clean manner without overhead - that could be anything from a size_t parameter for a sort or a datastructure for example.

        enum cpuidRange = iota(1, 10).map!(ctfeRepeater).array;
        @TemplateBenchmark!(0, cpuidRange) 
        @FunctionBenchmark!("Measure", iota(1, 10), (_) => [1, 2, 3, 4])(meas) 
        static int sum(string asmLine)(inout int[] input)
        {
            int tmp;
            foreach (i; input)
            {
                tmp += i;
                mixin("asm { ", asmLine, ";}");
            }
            return tmp;
        }
This made-up (pointless) benchmark measures how insert a number of cpuid instructions into the loop of a summing function affects it's runtime. My library writes the code from your specification as above to generate the instantiations and loop to measure the performance. As you might guess, the answer is a lot (CPUID is slow and serializing).

edit: https://github.com/maxhaton/chimpfella - I haven't bothered to add pmc support yet

Re: Rust is now overall faster than C in benchmarks

#146
Is it just me or has that 'benchmarks game' site been growing less navigable over time? It use to be easy to compare benchmarks across several languages. If that capability still exists somewhere it's buried and I'm not interested in puzzling it out. There are no side bars or menus or anything helpful.

Re: Rust is now overall faster than C in benchmarks

#147
post #126

Looking at the reverse-complement code, it appears that the Rust and C implementations are using different algorithms: https://benchmarksgame-team.pages.debian.net/benchmarksgame/... https://benchmarksgame-team.pages.debian.net/benchmarksgame/... On a quick inspection: - The Rust code is about twice as long. - The Rust code has CPU feature detection and SSE intrinsics, while the C code is more idiomatic. - The lookup…

What does "idiomatic" C even mean? It's a high level assembler and as such should not limit the creativity of programmers using it. C code that pretends it does not need to care about it's platform is not idiomatic, it's just suboptimal.

By "idiomatic C" I meant any of the following:

- Code that most C books/courses would teach you how to write

- Portable C code (arguably portability is one of C's biggest successes!)

- Code that you'd expect to find in the K&R book

Re: Rust is now overall faster than C in benchmarks

#148
post #104

Earlier quoted context omitted.

It's more to do with the fact that std::sort's definition is visible to the compiler and qsort() is not. Put qsort() code in stdlib.h, make it static and write a static intcmp() and you'll see the compiler inline that no problem.

Sure you can hard-code intcmp into qsort but then it would only work for arrays of ints. You could do some macro magic instead of templates e.g. `DEFINE_QSORT(int, intcmp)` which could stamp out `qsort_int` but that's not a part of the stdlib. C++ arguably gets this right since sort and sort will be separate functions, although templates are of course a footgun. And of course duping the logic for std::sort for a bunc…

The poster you are replying to didn't suggest hardcoding intcmp into qsort - just making it so the implmentation of qsort is available to the compiler when the comparison function is known (i.e. just like with C++).

When this is done, the compiler can inline qsort, and replace the indirect function call with an inlined version of intcmp, and then things are equivalent.

Re: Rust is now overall faster than C in benchmarks

#149

Apart from those benchmark games a lot of real world C is a lot less performant than people think it might be. I spent a fair amount of time reviewing C code in the last 5 years - and things that pop up in nearly every review are costly string operations. Linear counts due to the use of null terminated strings and extra allocations for substrings to attach null terminators, or just deep copies because ownership can’t…

Mostly agree with your comment but linear search through arrays of size less than a few hundred will typically beat more sophisticated structures such as red-black trees or hashtables. This is due to prefetching and avoidance of unpredictable pointer traversals. Asymptotic complexity is only that: asymptotic.

In many programs in many domains the sizes of these data structures will rarely exceed this limit.

Re: Rust is now overall faster than C in benchmarks

#150

Apart from those benchmark games a lot of real world C is a lot less performant than people think it might be. I spent a fair amount of time reviewing C code in the last 5 years - and things that pop up in nearly every review are costly string operations. Linear counts due to the use of null terminated strings and extra allocations for substrings to attach null terminators, or just deep copies because ownership can’t…

> null terminated strings feel like idiomatic C to most people

Doesn't that mean that null terminated strings is idiomatic C? That is, my understanding of the term idiomatic is that it is defined by whatever is most natural to users of a language regardless of whether it is the most performant.

Post reply on HN