top | item 45427614

(no title)

buybackoff | 5 months ago

I use an extension for arrays, something like:

    internal static class ArrayExtensions
    {
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public static ref T RefAtUnsafe<T>(this T[] array, nint index)
        {
    #if DEBUG
            return ref array[index];
    #else
            Debug.Assert((uint)index < array.Length, "RefAtUnsafe: (uint)index < array.Length");
            return ref Unsafe.Add(ref MemoryMarshal.GetArrayDataReference(array), (nuint)index);
    #endif
        }
    }
then your example turns into:

    public static void AddBatch(int[] a, int[] b, int count)
    {
        // Storing a reference is often more expensive that re-taking it in a loop, requires benchmarking
        for (nint i = 0; i < (uint)count; i++)
            a.RefAtUnsafe(i) += b.RefAtUnsafe(i);
    }

The JITted assembly: https://sharplab.io/#v2:EYLgxg9gTgpgtADwGwBYA0AXEBDAzgWwB8AB...

I'm convinced C# is so much better for high perf code, because yes it can do everything (including easy-to-use x-arch SIMD), but it lets one not bother about things that do not matter and use safe code. It's so pragmatic.

See also the top comments from a recent thread, I totally agree. https://news.ycombinator.com/item?id=45253012

BTW, do not use [MethodImpl(MethodImplOptions.AggressiveOptimization)], it disables TieredPGO, which is a huge thing for latest .NET versions.

discuss

order

bengarney|5 months ago

The world falls into two categories for me. "Must be fast" and "I don't care (much)". C/C++ is ideal for the first one, and C# is awesome for the second.

My argument isn't that C# is bad or performance is unachievable. It's that the mental overhead to write something that has consistent, high performance in C/C++ is very low. In other words, for the amount of mental effort, knowledge, and iteration it takes to write something fast + maintainable in C#, would I be better served by just writing it in C/C++?

The linked assembly is almost certainly non-optimal; compare to -O3 of the C version: https://godbolt.org/z/f5qKhrq1G - I automatically get SIMD usage and many other optimizations.

You can certainly make the argument that if X, Y, Z is done, your thing would be fast/faster. But that's exactly my argument. I don't want to do X, Y, Z to get good results if I don't have to (`return ref Unsafe.Add(ref MemoryMarshal.GetArrayDataReference(array), (nuint)index);` and using/not using `[MethodImpl(MethodImplOptions.AggressiveOptimization)]` are non-trivial mental overhead!).

I want to write `foo.bar` and get good, alloc free, optimized results... and more importantly, results that behave the same everywhere I deploy them, not dependent on language version, JIT specifics, etc.

If I was operating in a domain where I could not ever take the C/C++ path, these features of C# are of course very welcome. And in general more power/expressiveness is very good. But circling back, I wonder if my energy is better spent doing a C version than contorting C# to do what I want.

buybackoff|5 months ago

It just looks like you are much more fluent in C/C++ than in C#.