Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/25.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# 拳击会导致性能问题吗?我怎样才能防止拳击?_C#_.net_Performance_Boxing - Fatal编程技术网

C# 拳击会导致性能问题吗?我怎样才能防止拳击?

C# 拳击会导致性能问题吗?我怎样才能防止拳击?,c#,.net,performance,boxing,C#,.net,Performance,Boxing,装箱是否会导致代码中出现性能问题?我怎样才能防止拳击 void Main() { AreEqual<int>(12, 13); } public static bool AreEqual<T>(T a, T b) { return a.Equals(b); } 有时会,通常不会 你不能用这种方法预测性能问题。你是否有一个特定的程序太慢,你怀疑问题在于拳击 看看这个,它可以作为一个解决方法。但是-一如既往-确保这不是过早的优化 示例代码: stat

装箱是否会导致代码中出现性能问题?我怎样才能防止拳击

void Main()
{
    AreEqual<int>(12, 13);
}

public static bool AreEqual<T>(T a, T b)
{
    return a.Equals(b);
}

有时会,通常不会

你不能用这种方法预测性能问题。你是否有一个特定的程序太慢,你怀疑问题在于拳击

看看这个,它可以作为一个解决方法。但是-一如既往-确保这不是过早的优化

示例代码:

   static void foo<T>(ref T value) {
        //This is the ONLY way to treat value as bool, without boxing/unboxing objects
        if(value is bool) {
            TypedReference reference = __makeref(value); //get reference
            bool boolVal = __refvalue(reference,bool);   //get primitive value
            __refvalue(reference, bool) = !boolVal;      //set primitive value
        } else {
            value = default(T);
        }
    }
静态无效foo(参考T值){
//这是将值视为bool,而不装箱/取消装箱对象的唯一方法
if(值为bool){
TypedReference=\uu makeref(值);//获取引用
bool boolVal=\uu refvalue(reference,bool);//获取原语值
__refvalue(reference,bool)=!boolVal;//设置原语值
}否则{
值=默认值(T);
}
}

我的代码部分来自

装箱是否会导致代码中出现性能问题

只有你能回答这个问题。这是你的代码,这是你的代码的性能。对我来说,这不是问题,对你来说,可能是

我怎样才能防止拳击

void Main()
{
    AreEqual<int>(12, 13);
}

public static bool AreEqual<T>(T a, T b)
{
    return a.Equals(b);
}
通过强制编译器选择正确的重载。您的初始代码调用
object.Equals(object)
(在中重写),因为这是对每个无约束的
T
有效的唯一方法,它需要对传递的
int
参数进行装箱

,将其作为约束条件:

private static bool AreEqualEquatable<T>(T a, T b)
    where T : IEquatable<T>
{
    return a.Equals(b);
}
私有静态布尔是相等的(ta,tb)
其中T:i可满足
{
返回a等于(b);
}
它编译成这个IL:

IL_0000: nop
IL_0001: ldarga.s a
IL_0003: ldarg.1
IL_0004: constrained. !!T
IL_000a: callvirt instance bool class [mscorlib]System.IEquatable`1<!!T>::Equals(!0)
IL_000f: stloc.0
IL_0010: br.s IL_0012

IL_0012: ldloc.0
IL_0013: ret
IL_0000:nop
IL_0001:ldarga.s a
IL_0003:ldarg.1
IL_0004:受约束!!T
IL_000a:callvirt实例布尔类[mscorlib]系统。IEquatable`1::Equals(!0)
IL_000f:stloc.0
IL_0010:br.s IL_0012
IL_0012:ldloc.0
IL_0013:ret

因为编译器将尝试查找最专门的重载,在本例中,
IEquatable.Equals(T)
计算机为执行任务而执行的任何附加操作都会降低性能,性能降低是一回事,性能问题是另一回事。如果您试图实现一个包含数百万数据的高速数据结构,它可能会导致性能问题,但如果您只是编写一个在数据库和网络上执行许多查询的信息系统,那么我认为装箱不会给您带来性能问题

您应该始终分析应用程序,并查看影响性能的部分在哪里

因此,如果您试图比较两个整数,那么操作是(a==b)。如果为此编写函数,则需要额外的函数调用。如果添加其他泛型方法、匿名类型、装箱、取消装箱。。。那么所有这些额外的操作都会降低性能

如前所述,可以防止整数装箱

这是一个基准

private static void Main(string[] args)
{
    var sw1 = new Stopwatch();
    bool b1 = true;
    sw1.Start();
    for (int i = 0; i < 10 * 1000 * 1000; i++)
    {
        b1 = b1 ^ AreEqual(i, i + 1);
    }
    sw1.Stop();
    Console.WriteLine(b1);
    Console.WriteLine(sw1.ElapsedTicks);


    var sw2 = new Stopwatch();
    bool b2 = true;
    sw2.Start();
    for (int i = 0; i < 10 * 1000 * 1000; i++)
    {
        b2 = b2 ^ AreEqualEx(i, i + 1);
    }
    sw2.Stop();
    Console.WriteLine(b2);
    Console.WriteLine(sw2.ElapsedTicks);
}

public static bool AreEqual<T>(T a, T b)
{
    return a.Equals(b);
}

public static bool AreEqualEx<T>(T a, T b) where T:IEquatable<T>
{
    return a.Equals(b);
}
private static void Main(字符串[]args)
{
var sw1=新秒表();
bool b1=真;
sw1.Start();
对于(int i=0;i<10*1000*1000;i++)
{
b1=b1^A相等(i,i+1);
}
sw1.Stop();
控制台写入线(b1);
Console.WriteLine(sw1.ElapsedTicks);
var sw2=新秒表();
布尔b2=真;
sw2.Start();
对于(int i=0;i<10*1000*1000;i++)
{
b2=b2^arequalex(i,i+1);
}
sw2.Stop();
控制台写入线(b2);
Console.WriteLine(sw2.ElapsedTicks);
}
公共静态布尔相等(T a,T b)
{
返回a等于(b);
}
公共静态布尔是等价的(ta,tb),其中T:i可满足
{
返回a等于(b);
}
结果是

正确
254379
正确
35514


配置它。这是你的应用程序的缓慢部分吗?你没有在IL下发布这段代码,询问box命令是什么吗?在这个问题上有很多评论指出什么是拳击,为什么会发生在你的代码中你每秒拳击几百万个物体吗?我只是好奇。。为什么要投反对票?!我们不喜欢删除和重新发布问题。你本可以改进上一个的。