关于性能:C#方法 – 调用比代码更快

C# Method-Call faster than just code

我想通过将代码放入方法而不是仅仅调用它来测试浪费了多少时间。

令我惊讶的是,方法调用更快,我问自己:为什么?

这是代码:hobjects是图像处理库"halcon"的一部分,在方法调用中通常与"out"一起使用,因此不要担心可怕的外观;-)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
    static void Main(string[] args)
    {
        int runs = 900000;
        HObject hob1;
        HObject hob2;
        HObject hob3;
        HObject hob4;
        HObject hob5;
        HObject hob6;

        DateTime t1 = DateTime.Now;

        for ( int i = 0; i < runs; i++ )
        {
            doItMethod(out hob1, out hob2, out hob3, out hob4, out hob5, out hob6);
        }

        TimeSpan ts1 = TimeSpan.FromTicks(DateTime.Now.Ticks - t1.Ticks);

        DateTime t2 = DateTime.Now;

        for ( int i = 0; i < runs; i++ )
        {
            HOperatorSet.GenEmptyObj(out hob1);
            HOperatorSet.GenEmptyObj(out hob2);
            HOperatorSet.GenEmptyObj(out hob3);
            HOperatorSet.GenEmptyObj(out hob4);
            HOperatorSet.GenEmptyObj(out hob5);
            HOperatorSet.GenEmptyObj(out hob6);

            hob1.Dispose();
            hob2.Dispose();
            hob3.Dispose();
            hob4.Dispose();
            hob5.Dispose();
            hob6.Dispose();
        }

        TimeSpan ts2 = TimeSpan.FromTicks(DateTime.Now.Ticks - t2.Ticks);

        Console.WriteLine("Zeitspanne Methodenaufruf :" + ts1.TotalMilliseconds.ToString());
        Console.WriteLine("Zeitspanne direkter Aufruf:" + ts2.TotalMilliseconds.ToString());

        Console.ReadKey();
    }


    static void doItMethod(out HObject hobOut1, out HObject hobOut2, out HObject hobOut3, out HObject hobOut4, out HObject hobOut5, out HObject hobOut6)
    {
        HOperatorSet.GenEmptyObj(out hobOut1);
        HOperatorSet.GenEmptyObj(out hobOut2);
        HOperatorSet.GenEmptyObj(out hobOut3);
        HOperatorSet.GenEmptyObj(out hobOut4);
        HOperatorSet.GenEmptyObj(out hobOut5);
        HOperatorSet.GenEmptyObj(out hobOut6);

        hobOut1.Dispose();
        hobOut2.Dispose();
        hobOut3.Dispose();
        hobOut4.Dispose();
        hobOut5.Dispose();
        hobOut6.Dispose();
    }


你应该用秒表

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
 //add using System.Diagnostics;

 public static void Main()
    {
        int runs = 900000;
        HObject hob1;
        HObject hob2;
        HObject hob3;
        HObject hob4;
        HObject hob5;
        HObject hob6;

        Stopwatch t1 = new Stopwatch();

        t1.Start();

        for ( int i = 0; i < runs; i++ )
        {
            doItMethod(out hob1, out hob2, out hob3, out hob4, out hob5, out hob6);
        }

        t1.Stop();


        Stopwatch t2 = new Stopwatch();
        t2.Start();

        for ( int i = 0; i < runs; i++ )
        {
            HOperatorSet.GenEmptyObj(out hob1);
            HOperatorSet.GenEmptyObj(out hob2);
            HOperatorSet.GenEmptyObj(out hob3);
            HOperatorSet.GenEmptyObj(out hob4);
            HOperatorSet.GenEmptyObj(out hob5);
            HOperatorSet.GenEmptyObj(out hob6);

            hob1.Dispose();
            hob2.Dispose();
            hob3.Dispose();
            hob4.Dispose();
            hob5.Dispose();
            hob6.Dispose();
        }
        t2.Stop();



        Console.WriteLine("Zeitspanne Methodenaufruf :" + t1.ElapsedMilliseconds);
        Console.WriteLine("Zeitspanne direkter Aufruf:" + t2.ElapsedMilliseconds);

        Console.ReadKey();
    }

谢谢大家!我得到了答案。

正如尤金·里克怀疑的那样,这是一个GC伪制品。

强制垃圾收集使方法调用版本比直接代码慢。


我用秒表得到了正确的结果:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
Method: 00:00:04.5573170
Code: 00:00:04.5539918



static void Main(string[] args)
    {
        int runs = 1000;
        HObject hob1;
        HObject hob2;
        HObject hob3;
        HObject hob4;
        HObject hob5;
        HObject hob6;

        Stopwatch sw = new Stopwatch();
        sw.Start();

        for (int i = 0; i < runs; i++)
        {
            doItMethod(out hob1, out hob2, out hob3, out hob4, out hob5, out hob6);
        }

        sw.Stop();
        Console.WriteLine(sw.Elapsed);

        sw = Stopwatch.StartNew();

        for (int i = 0; i < runs; i++)
        {
            HOperatorSet.GenEmptyObj(out hob1);
            HOperatorSet.GenEmptyObj(out hob2);
            HOperatorSet.GenEmptyObj(out hob3);
            HOperatorSet.GenEmptyObj(out hob4);
            HOperatorSet.GenEmptyObj(out hob5);
            HOperatorSet.GenEmptyObj(out hob6);

            hob1.Dispose();
            hob2.Dispose();
            hob3.Dispose();
            hob4.Dispose();
            hob5.Dispose();
            hob6.Dispose();
        }

        sw.Stop();
        Console.WriteLine(sw.Elapsed);

        Console.ReadKey();
    }