Why are structures slower than classes?

I am creating a C # console application. I have some critical paths and I thought that creating structures would be faster than creating classes, since I don't need garbage collection for structures. However, in my test, I found the opposite.

In the example below, I create 1000 structures and 1000 classes.

class Program
{
    static void Main(string[] args)
    {
        int iterations = 1000;
        Stopwatch sw = new Stopwatch();

        sw.Start();
        List<Struct22> structures = new List<Struct22>();
        for (int i = 0; i < iterations; ++i)
        {
            structures.Add(new Struct22());
        }
        sw.Stop();
        Console.WriteLine($"Struct creation consumed {sw.ElapsedTicks} ticks");

        Stopwatch sw2 = new Stopwatch();
        sw2.Start();
        List<Class33> classes = new List<Class33>();
        for (int i = 0; i < iterations; ++i)
        {
            classes.Add(new Class33());
        }
        sw2.Stop();
        Console.WriteLine($"Class creation consumed {sw2.ElapsedTicks} ticks");


        Console.ReadLine();
    }
}

My classe / struct are simple:

class Class33
{
    public int Property { get; set; }
    public int Field;
    public void Method() { }
}

struct Struct22
{
    public int Property { get; set; }
    public int Field;
    public void Method() { }
}

Results (drum, please ...)

Struct creating consuming 3038 ticks
Class creating consuming 404 ticks

So the question is: Why does a class take about 10 times the amount of time than Struct?

EDIT. I made the Make Something program by simply assigning integers to the properties.

 static void Main(string[] args)
    {
        int iterations = 10000000;
        Stopwatch sw = new Stopwatch();

        sw.Start();
        List<Struct22> structures = new List<Struct22>();
        for (int i = 0; i < iterations; ++i)
        {
            Struct22 s = new Struct22()
            {
                Property = 2,
                Field = 3
            };
            structures.Add(s);
        }
        sw.Stop();
        Console.WriteLine($"Struct creating consuming {sw.ElapsedTicks} ticks");

        Stopwatch sw2 = new Stopwatch();
        sw2.Start();
        List<Class33> classes = new List<Class33>();
        for (int i = 0; i < iterations; ++i)
        {
            Class33 c = new Class33()
            {
                Property = 2,
                Field = 3
            };
            classes.Add(c);
        }
        sw2.Stop();
        Console.WriteLine($"Class creating consuming {sw2.ElapsedTicks} ticks");


        Console.ReadLine();
    }

and the result amazes me. Classes are still at least 2x, but the simple fact of assigning integers had an effect of 20x!

Struct creating consuming 903456 ticks
Class creating consuming 4345929 ticks

EDIT: , :

class Class33
{
    public int Property { get; set; }
    public int Field;
}

struct Struct22
{
    public int Property { get; set; }
    public int Field;
}
+4
3

, , (, , ) .

structures.Add(new Struct22()); :

  • A Struct22 .
  • Add, , .

, Add , Struct22 .


, , , :

private static void StructDemo()
{
    List<Struct22> list = new List<Struct22>();

    Struct22 s1 = new Struct22() { Property = 2, Field = 3 };  // #1
    list.Add(s1);                            // This creates copy #2
    Struct22 s3 = list[0];                   // This creates copy #3

    // Change properties:
    s1.Property = 777;
    // list[0].Property = 888;    <-- Compile error, NOT possible
    s3.Property = 999;

    Console.WriteLine("s1.Property = " + s1.Property);
    Console.WriteLine("list[0].Property = " + list[0].Property);
    Console.WriteLine("s3.Property = " + s3.Property);
}

, , Add(), list[0] :

s1.Property = 777
list [0].Property = 2
s3.Property = 999

, , , .

+1

, vs . , , , .

, .

, , . , Structs. , , , , .

, , , , .

10000 
Struct creation consumed 2333 ticks
Class creation consumed 1616 ticks

100000
Struct creation consumed 5672 ticks
Class creation consumed 8459 ticks

1000000
Struct creation consumed 73462 ticks
Class creation consumed 221704 ticks
0

List<T> T .

, , ...

1000 , 10 .

, , , , List List of Class List of Struct...

Try creating a list with initial initialization, for your code it should be:

new List<Struct22>(1000)

in this case, the internal array will not be recreated, and the structural case will work much faster

0
source

Source: https://habr.com/ru/post/1662559/


All Articles