不同参数类型的调用性能

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

把第二套结果减去第一套的结果可以看出,对变量的访问性能的差别。

指针还是王。数组较慢,传值的结构最慢。传址的性能较好。

测试结果只作为参考,随着环境,系统版本的变化可能变化较大。

猜你喜欢

转载自blog.csdn.net/KAMILLE/article/details/2700939
今日推荐