C# Method Parameter Performance

Explore the performance impact of parameter order. Understand the concept of enregistration.

Parameter order. This influences method performance. It influences the enregistration of variables. We can sometimes enhance performance by reordering parameters in methods.Parameter OptimizationOptimization

We review the reasons why this is effective. With newer 64-bit processors, the speed advantage of this optimization is much less.

An example. C# methods use the same optimizations available in unmanaged languages with FASTCALL. We can optimize by placing frequently-used variables in the first two parameters.Benchmark
Info: The exact logic tests in Test1 and Test2 are unimportant here. Two parameters are tested in the tight loop in Test1 and Test2.
Test1: Here the variables tested are the first parameters. They are more likely to be enregistered.
Test2: In this code, we test the variables that come last in the parameter list.
Warning: On newer 64-bit processors, try increasing the number of iterations on this benchmark. The speedup is less dramatic here.
C# program that benchmarks parameter usage using System; using System.Diagnostics; class Program { static bool Test1(int a, int b, int c, int d, int e, int f) { // This method tests the first two parameters in the loop. for (int i = 5; i < 10000000; i++) { if (a == i) { return true; } if (b == i) { return true; } } if (c == 1 || d == 1 || e == 1) { return true; } return false; } static bool Test2(int a, int b, int c, int d, int e, int f) { // This method tests the last two parameters in the loop. for (int i = 5; i < 10000000; i++) { if (e == i) { return true; } if (f == i) { return true; } } if (a == 1 || b == 1 || c == 1) { return true; } return false; } static void Main() { const int m = 100; Stopwatch s1 = Stopwatch.StartNew(); for (int i = 0; i < m; i++) { Test1(3, 3, 3, 3, 3, 3); } s1.Stop(); Stopwatch s2 = Stopwatch.StartNew(); for (int i = 0; i < m; i++) { Test2(3, 3, 3, 3, 3, 3); } s2.Stop(); Console.WriteLine("{0},{1}", s1.ElapsedMilliseconds, s2.ElapsedMilliseconds); Console.Read(); } } Output X86 platform. Test first 2 parameters: 952 ms Test last 2 parameters: 2224 ms

Parameters. When you compile and execute a C# method, the parameters are pushed onto the stack and the method is called. Internally, that method then uses the parameters on the stack.
However: Microsoft compilers have an optimization called FASTCALL, in which the first two parameters in x86 are passed as registers.

Understanding registers. An enregistered variable in machine code is one that is stored in the fastest processor cache. Access to it is extremely fast.
Info: In loops, the iterator variable i is normally stored in a register. The variable i is often part of affine expressions.

Discussion. Rarely is parameter order likely to affect results. But you may find a method that uses many parameters. Often, such methods are focused on optimization.
And: These methods often defy object-oriented best practices. This technique could improve these methods.
Quote: For FASTCALL, compiler will try to pass arguments in registers, if not enough caller will pushed them into stack still in an order from right to left.
Quote: Stack cleanup is done by callee. It is called FASTCALL because if arguments can be passed in registers (for 64bit CPU the maximum number is 6), no stack push/clean up is needed.
x86 Disassembly: wikibooks.org

A summary. The ordering of parameters affects the likelihood they will be enregistered. Having your loop variables in registers is faster. Knowledge of registers can help C# code.

© 2007-2020 Sam Allen. Every person is special and unique. Send bug reports to info@dotnetperls.com.