using System; public struct Svector { public Svector(int x, int y, int z) { this.x = x; this.y = y; this.z = z; } public int x; public int y; public int z; } public class Cvector { public Cvector(int x, int y, int z) { this.x = x; this.y = y; this.z = z; } public int x; public int y; public int z; } class tester { static int fun1(int x, int y, int z) { //return x + y - z - z + 1; return 1; } static int fun2(ref int x, ref int y, ref int z) { //return x + y - z - z + 1; return 1; } static int fun3(Svector vec) { //return vec.x + vec.y - vec.z - vec.z + 1; return 1; } static int fun4(ref Svector vec) { //return vec.x + vec.y - vec.z - vec.z + 1; return 1; } static int fun5(Cvector vec) { //return vec.x + vec.y - vec.z - vec.z + 1; return 1; } static int fun6(ref Cvector vec) { //return vec.x + vec.y - vec.z - vec.z + 1; return 1; } static int fun7(int[] array) { //return array[0] + array[1] - array[2] - array[2] + 1; return 1; } static int fun8(ref int[] array) { //return array[0] + array[1] - array[2] - array[2] + 1; return 1; } unsafe static int fun9(int* array) { //return array[0] + array[1] - array[2] - array[2] + 1; return 1; } unsafe static void Main() { int COUNT = 1000000000; Svector svec = new Svector(1, 1, 1); Cvector cvec = new Cvector(1, 1, 1); int[] array = new int[] { 1, 1, 1 }; System.Diagnostics.Stopwatch watch; int* pstack = stackalloc int[3]; pstack[0] = 1; pstack[1] = 1; pstack[2] = 1; int* pheap = (int*)System.Runtime.InteropServices.Marshal.AllocHGlobal(12); pheap[0] = 1; pheap[1] = 1; pheap[2] = 1; watch = new System.Diagnostics.Stopwatch(); watch.Reset(); watch.Start(); for (int i = 1; i < COUNT; ) { i += fun1(i, i, i); } watch.Stop(); Console.WriteLine("传值3个int:" + watch.ElapsedMilliseconds); watch = new System.Diagnostics.Stopwatch(); watch.Reset(); watch.Start(); for (int i = 1; i < COUNT; ) { i += fun2(ref i, ref i, ref i); } watch.Stop(); Console.WriteLine("传址3个int:" + watch.ElapsedMilliseconds); watch = new System.Diagnostics.Stopwatch(); watch.Reset(); watch.Start(); for (int i = 1; i < COUNT; ) { i += fun3(svec); } watch.Stop(); Console.WriteLine("传值12Byte的结构:" + watch.ElapsedMilliseconds); watch = new System.Diagnostics.Stopwatch(); watch.Reset(); watch.Start(); for (int i = 1; i < COUNT; ) { i += fun4(ref svec); } watch.Stop(); Console.WriteLine("传址12Byte的结构:" + watch.ElapsedMilliseconds); watch = new System.Diagnostics.Stopwatch(); watch.Reset(); watch.Start(); for (int i = 1; i < COUNT; ) { i += fun5(cvec); } watch.Stop(); Console.WriteLine("传值12Byte的类:" + watch.ElapsedMilliseconds); watch = new System.Diagnostics.Stopwatch(); watch.Reset(); watch.Start(); for (int i = 1; i < COUNT; ) { i += fun6(ref cvec); } watch.Stop(); Console.WriteLine("传址12Byte的类:" + watch.ElapsedMilliseconds); watch = new System.Diagnostics.Stopwatch(); watch.Reset(); watch.Start(); for (int i = 1; i < COUNT; ) { i += fun7(array); } watch.Stop(); Console.WriteLine("传值int[3]:" + watch.ElapsedMilliseconds); watch = new System.Diagnostics.Stopwatch(); watch.Reset(); watch.Start(); for (int i = 1; i < COUNT; ) { i += fun8(ref array); } watch.Stop(); Console.WriteLine("传址int[3]:" + watch.ElapsedMilliseconds); watch = new System.Diagnostics.Stopwatch(); watch.Reset(); watch.Start(); for (int i = 1; i < COUNT; ) { i += fun9(pstack); } watch.Stop(); Console.WriteLine("传栈指针:" + watch.ElapsedMilliseconds); watch = new System.Diagnostics.Stopwatch(); watch.Reset(); watch.Start(); for (int i = 1; i < COUNT; ) { i += fun9(pheap); } watch.Stop(); Console.WriteLine("传堆指针:" + watch.ElapsedMilliseconds); } }
我的测试结果如下:
传值3个int:1056
传址3个int:3959
传值12Byte的结构:4219
传址12Byte的结构:1582
传值12Byte的类:1054
传址12Byte的类:1054
传值int[3]:1582
传址int[3]:1611
传栈指针:1662
传堆指针:1109
要注意一点,这里只是测试作为参数传递的性能差别,而且可能还不够全面。
如果调用前要生成对象,例如 fun7(new int[3]{1,1,1}),性能必定低下。
从结果可以看出,结构传值的性能不理想,多个参数ref传递性能不理想。
把注解去掉,结果如下:
传值3个int:2640
传址3个int:5925
传值12Byte的结构:9868
传址12Byte的结构:3127
传值12Byte的类:2901
传址12Byte的类:3340
传值int[3]:4650
传址int[3]:4746
传栈指针:2109
传堆指针:1905
把第二套结果减去第一套的结果可以看出,对变量的访问性能的差别。
指针还是王。数组较慢,传值的结构最慢。传址的性能较好。
测试结果只作为参考,随着环境,系统版本的变化可能变化较大。