我只是看了一个例子,在里面我看到了代码
return new IntPtr(handle);在仔细查看我们的代码后,我发现我们已经使用了类似的模式,但在我们的代码中,我们使用了几乎相同的东西:
return (IntPtr)handle;这两个镜头之间有区别吗?第二个函数会不会“更好”,因为它没有分配新的内存,或者强制转换只是在下面隐藏了相同的构造函数?
发布于 2009-08-06 05:36:22
在你的例子中,我猜句柄是一个整数值?IntPtr声明了从Int32 (int)和Int64 (long)的显式转换,它只是调用相同的构造函数:
public static explicit operator IntPtr(int value)
{
return new IntPtr(value);
}因此,除了可能的可读性问题之外,实际上没有其他区别。
发布于 2009-08-06 05:37:03
Reflector说,无论如何,演员都是在幕后调用构造函数:
[Serializable, StructLayout(LayoutKind.Sequential), ComVisible(true)]
public struct IntPtr : ISerializable
{
...
[ReliabilityContract(Consistency.MayCorruptInstance, Cer.MayFail)]
public static explicit operator IntPtr(int value)
{
return new IntPtr(value);
}
}发布于 2010-12-12 17:08:27
所以这个帖子都是空谈,没有数字,所以让我们来谈谈指标。我使用Visual Studio 2010运行了一些测试代码,以获得一些性能指标
我通过计算这两种方法在Debug和Release模式(未优化,然后优化)下运行10次测试,每次迭代1000万次的平均时间,得到了这些指标:
(调试)投射方式:~32ms分配方式:~26ms
(释放)投射方式:~20ms分配方式:~22ms
同样有趣的是,仅使用gcnew将这些指标与托管C++的类似代码进行比较,结果会有很大不同。
又是同样的设置。除了比较转换方法:“IntPtr^Ptr= (IntPtr) i;”与分配方法:“IntPtr^Ptr= (IntPtr) i;”。
(Debug)转换方式:~91ms分配方式:~127ms
(释放)投射方式:~22ms分配方式:~124ms
现在,如果你正在挠头,问为什么C#比托管C++快这么多,答案是它不快,使用IntPtr最有效的方法是作为值类型,而不是对值类型的引用。例如像这样的"IntPtr ptr = (IntPtr) i;“。这将给你大约24ms(调试更多)或(~22释放模式)。看看上面的编译器是如何优化它的,以获得22ms而不是90ms。
结论在C#中,除非您正在查看非常非常紧凑的代码,否则这无关紧要。我认为随着我的代码的发布,它实际上是在优化强制转换,因为注释掉强制转换得到了同样的~22ms。但在很大程度上,编译器在C#中支持这一点,至少VS2010是这样的。然而,在托管C++/CLI中,如果您正在查看具有最小性能约束的代码,那么请注意。编译器不会自动优化gcnew分配到造型方法,而且它几乎快了6倍……我实际上在C++/CLI中遇到了这个特殊的问题,这就是当我处理一些实时音频处理时,我在这个线程上发帖的原因。我的代码(C#):(我的托管C++代码非常类似,只是我必须自己编写Average(),并使用console而不是消息框来输出)。
static void Main()
{
List<int> castTimings = new List<int>();
List<int> allocTimings = new List<int>();
for (int i = 0; i < TEST_RUNS; ++i)
{
castTimings.Add(RunCastMethod().Milliseconds);
allocTimings.Add(RunAllocationMethod().Milliseconds);
}
MessageBox.Show(string.Format("Casting Method took: {0}ms", castTimings.Average() ));
MessageBox.Show(string.Format("Allocation Method took: {0}ms", allocTimings.Average() ));
}
private static TimeSpan RunAllocationMethod() {
DateTime start = DateTime.Now;
for (int i = 0; i < TEST_ITERATIONS; ++i)
{
IntPtr ptr = new IntPtr(i);
}
return ( DateTime.Now - start );
}
private static TimeSpan RunCastMethod()
{
DateTime start = DateTime.Now;
for (int i = 0; i < TEST_ITERATIONS; ++i)
{
IntPtr ptr = (IntPtr) i;
}
return (DateTime.Now - start);
}https://stackoverflow.com/questions/1237122
复制相似问题