gpt4 book ai didi

c# - 为什么反射比对象初始化更快?

转载 作者:行者123 更新时间:2023-11-30 13:35:25 26 4
gpt4 key购买 nike

  1. 抱歉非计算机科学术语(自学)
  2. 抱歉不正确的术语(任何愿意编辑的人,请编辑,(自学))

我尽可能多地进行了搜索,但我对所搜索内容的术语知识有限,但我无法找到并回答我所寻找的问题。

我很惊讶地发现通过反射向对象填充数据比使用对象初始化更快。

我为此制作了一个测试控制台应用程序。首先是测试类,

class TestClass
{
public string PropertyOne { get; set; }
public string PropertyTwo { get; set; }
public string PropertyThree { get; set; }
public string PropertyFour { get; set; }
public string PropertyFive { get; set; }
public string PropertySix { get; set; }
public string PropertySeven { get; set; }
public string PropertyEight { get; set; }
public string PropertyNine { get; set; }
public string PropertyTen { get; set; }
}
}

然后是获取数据的方法,首先是反射(reflection),

public static void ReflectionTest()
{
for (int i = 0; i < 10000000; i++)
{
TestClass testClass = new TestClass();
Type type = testClass.GetType();
PropertyInfo[] properties = type.GetProperties();
foreach (var propertyInfo in properties)
{
switch (propertyInfo.Name)
{
case nameof(testClass.PropertyOne):
propertyInfo.SetValue(testClass, "PropertyOne" + i);
break;
case nameof(testClass.PropertyTwo):
propertyInfo.SetValue(testClass, "PropertyTwo" + i);
break;
case nameof(testClass.PropertyThree):
propertyInfo.SetValue(testClass, "PropertyThree" + i);
break;
case nameof(testClass.PropertyFour):
propertyInfo.SetValue(testClass, "PropertyFour" + i);
break;
case nameof(testClass.PropertyFive):
propertyInfo.SetValue(testClass, "PropertyFive)" + i);
break;
case nameof(testClass.PropertySix):
propertyInfo.SetValue(testClass, "PropertySix" + i);
break;
case nameof(testClass.PropertySeven):
propertyInfo.SetValue(testClass, "PropertySeven" + i);
break;
case nameof(testClass.PropertyEight):
propertyInfo.SetValue(testClass, "PropertyEight" + i);
break;
case nameof(testClass.PropertyNine):
propertyInfo.SetValue(testClass, "PropertyNine" + i);
break;
case nameof(testClass.PropertyTen):
propertyInfo.SetValue(testClass, "PropertyTen" + i);
break;
}
}
TestClasses.Add(testClass);
}
}

接下来是对象的初始化,

public static void InitializationTest()
{
for (int i = 0; i < 10000000; i++)
{
TestClass testClass = new TestClass
{
PropertyOne = "PropertyOne" + i,
PropertyTwo = "PropertyTwo" + i,
PropertyThree = "PropertyThree" + i,
PropertyFour = "PropertyFour" + i,
PropertyFive = "PropertyFive)" + i,
PropertySix = "PropertySix" + i,
PropertySeven = "PropertySeven" + i,
PropertyEight = "PropertyEight" + i,
PropertyNine = "PropertyNine" + i,
PropertyTen = "PropertyTen" + i
};
TestClasses.Add(testClass);
}
}

和测试代码

static List<TestClass> TestClasses { get; set; } = new List<TestClass>();

static void Main(string[] args)
{
Stopwatch sw = new Stopwatch();
sw.Start();
ReflectionTest();
Console.WriteLine($"Reflection Test time: {sw.Elapsed}");
sw.Reset();
sw.Start();
InitializationTest();
Console.WriteLine($"Initialization Test time: {sw.Elapsed}");
sw.Stop();
}

使用此代码反射比使用对象初始化快 20%。这是什么原因?

编辑:在代码中添加 TestClasses.Clear(); 表明“对象初始化”快了将近两倍。感谢您的回复和评论。

最佳答案

这样的测量没有意义 - 否则每个人都会使用反射而不是对象实例。

结果困惑的主要原因是所有项目都被添加到同一个列表中。以不同顺序调用测试,InitializationTest 性能更好。

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

sw.Start();
InitializationTest();
Console.WriteLine($"Initialization Test time: {sw.Elapsed}");
sw.Stop();
sw.Reset();

sw.Start();
ReflectionTest();
Console.WriteLine($"Reflection Test time: {sw.Elapsed}");
sw.Stop();
sw.Reset();

Console.ReadLine();
}

正如 Matthew Watson 在评论中所说:“更好的是,根本不要将列表用作计时的一部分。我们应该计时创建对象所需的时间 - 而不是创建对象所需的时间填写一个非常大的列表。”


反射测试包含不必要的成本:重复 GetProperties 调用,switch 中的测试条件

public static void ReflectionTest()
{
PropertyInfo[] properties = typeof(TestClass).GetProperties();
for (int i = 0; i < 10000000; i++)
{
TestClass testClass = new TestClass();
foreach (var propertyInfo in properties)
{
propertyInfo.SetValue(testClass, propertyInfo.Name + i);
}
TestClasses.Add(testClass);
}
}

关于c# - 为什么反射比对象初始化更快?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58569426/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com