Comment

Comment by int_19h

It was actually capable of inlining to the point where it could do some tricks that you'd normally expect only from C++. For example, if you use generics and structs rather than delegates to implement higher-order functions, like so:

    class Program {
        interface IFunc<T1, T2, TResult> {
            TResult Invoke(T1 x1, T2 x2);
        }

        struct AddInt32 : IFunc<int, int, int> {
            public int Invoke(int x, int y) {
                return x + y;
            }
        }

        static T FoldLeft<T, F>(T[] xs, F f) where F : IFunc<T, T, T> {
            var res = xs[0];
            for (int i = 1; i < xs.Length; ++i) {
                res = f.Invoke(res, xs[i]);
            }
            return res;
        }

        static void Main() {
            Console.ReadKey();
            int[] xs = { 1, 2, 3, 5, 8 };
            int res = FoldLeft(xs, new AddInt32());
            Console.WriteLine(res);
        }
    }
I compiled and ran it with 3.5 SP1 x86 (the old 64-bit JIT wasn't good, and won't inline in this case). It didn't inline FoldLeft, but it did inline AddInt32 into the loop - this is from VS debugger disassembly:

            for (int i = 1; i < xs.Length; ++i) {
    017B0106  mov         edx,1  
    017B010B  mov         edi,dword ptr [ecx+4]  
    017B010E  cmp         edi,1  
    017B0111  jle         017B011E  
                res = f.Invoke(res, xs[i]);
    017B0113  mov         eax,dword ptr [ecx+edx*4+8]  
    017B0117  add         esi,eax  
            for (int i = 1; i < xs.Length; ++i) {
    017B0119  inc         edx  
    017B011A  cmp         edi,edx  
    017B011C  jg          017B0113  
            }
parent int_19h 10 years ago

Discussion

Live from the official Hacker News API

A modern reader for Hacker News · SvelteKit + Skeleton