Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/283.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# IntPtr演员与新演员_C#_Intptr - Fatal编程技术网

C# IntPtr演员与新演员

C# IntPtr演员与新演员,c#,intptr,C#,Intptr,我只是在看一个例子,在其中我看到了代码 return new IntPtr(handle); 在翻遍我们的代码后,我发现我们已经使用了类似的模式,但在我们的代码中,我们有几乎相同的东西: return (IntPtr)handle; 这两者之间有区别吗?第二个是否会“更好”,因为它不会分配新内存,还是强制转换只是将同一个构造函数隐藏在下面?在您的示例中,我猜句柄是一个整数值?IntPtr声明了从Int32(int)和Int64(long)的显式转换,该转换只调用相同的构造函数: public

我只是在看一个例子,在其中我看到了代码

return new IntPtr(handle);
在翻遍我们的代码后,我发现我们已经使用了类似的模式,但在我们的代码中,我们有几乎相同的东西:

return (IntPtr)handle;

这两者之间有区别吗?第二个是否会“更好”,因为它不会分配新内存,还是强制转换只是将同一个构造函数隐藏在下面?

在您的示例中,我猜句柄是一个整数值?IntPtr声明了从Int32(int)和Int64(long)的显式转换,该转换只调用相同的构造函数:

public static explicit operator IntPtr(int value)
{
    return new IntPtr(value);
}

因此,除了可能的可读性问题之外,实际上没有什么区别。

因为
IntPtr
是一种值类型,所以使用
new
不会分配任何内存

从技术上讲,调用仍然编译为不同的IL-一个调用构造函数,另一个调用显式转换操作符。我不确定在通过JIT考试后,这两者之间是否有任何实际的区别,然而——很可能没有(尽管我怀疑你在实践中会注意到这两种方式,这是一种女性优化)

无论如何,cast比使用构造函数更为惯用,因此我建议仅出于这个原因就使用它。

说cast在幕后调用构造函数:

[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);
    }

}

因此,这个线程是所有的谈话,没有数字,所以让我们谈谈指标。我运行了一些测试代码,使用VisualStudio2010和

我通过计算每种方法在10次测试运行中的平均时间得到了这些指标,每次测试运行在调试然后发布模式(非优化然后优化)下,迭代次数为1000万次:

(调试) 铸造方法:~32毫秒 分配方法:~26毫秒

(发布) 铸造方法:~20ms 分配方法:~22毫秒

同样有趣的是,只使用GCNEW将这些度量与类似的代码与托管C++进行比较,结果有很大不同。 同样的设置。除了比较铸造方法:“IntPtr^ptr=(IntPtr)i;”和分配方法:“IntPtr^ptr=(IntPtr)i;”之外

(调试) 铸造方法:~91ms 分配方式:~127ms

(发布) 铸造方法:~22ms 分配方式:~124ms

现在如果你在努力地说,为什么C比管理C++快得多,答案是:不是。使用IntPtr最有效的方法是作为值类型,而不是对值类型的引用。例如,“IntPtr ptr=(IntPtr)i;”。这将为您提供约24毫秒(调试更多)或(~22发布模式)。看看上面编译器是如何优化的,以得到22ms而不是90ms

结论在C#中,除非您看到的是非常紧凑的代码,否则这并不重要。我认为我发布的代码实际上是在优化演员阵容,因为对演员阵容的评论给出了相同的~22ms。但在C语言中,编译器在很大程度上支持这一点,至少VS2010支持这一点。但是,在托管C++/CLI中,如果您查看的代码甚至具有最小的性能约束,请注意。编译器不会自动优化新的强制转换方法分配,而且速度快了近6倍。。。实际上,我在C++/CLI中遇到了这个特殊的问题,这正是我在处理一些实时音频处理时在这个线程上发表文章的原因。我的代码(C ^):(我的托管C++代码非常相似,除了我必须自己写平均值),并且使用控制台来输出而不是消息框。
static void Main()
{
List castTimings=新列表();
List ALLOCTINGS=新列表();
对于(int i=0;i
IntPtr是值类型的事实并不意味着new不会分配内存。事实上,最好使用new来确保结构正确初始化。我认为Pavel的意思是,它不使用任何其他情况下不会使用的内存。显然,复制值类型将意味着使用更多的内存:)使用(或不使用)
new
绝对不会给您带来任何好处来确保结构正确初始化。对于初学者来说,您首先不能有一个“未正确初始化的结构”,因为编译器将强制对局部变量进行初始化,并默认初始化所有其他内容。此外,在这里实际上不太可能发生任何复制。它将只使用一个寄存器(或32位机器上的两个寄存器)直接存储值,并立即返回。Pavel,我意识到我并不完全清楚我的意思。如果使用包含公共属性而非字段的结构,如果在使用时未为所有属性提供值,则会出现“使用未赋值变量”编译器错误。你可以通过更新结构来解决这个问题。公共结构T{public string S{get;set;}public int I{get;set;}}T;t、 S=“你好”;将导致编译器错误,但T=new T();t、 S=“你好”;不会。
    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);
    }