我试图从性能的角度了解两种解决方案中的哪一种是首选。 比如我有两段代码:
1) 装箱/拆箱
int val = 5;
Session["key"] = val;
int val2 = (int)Session["key"];
2) 转换(IntObj 有 int Value 属性来存储 int)
IntObj val = new IntObj(5);
Session["key"] = val;
int val2 = ((IntObj )Session["key"]).Value;
这些例子之间的内存管理区别是什么? 有没有更快的方法来执行此类操作?
注意: Session
只是举个例子,可以是任意Dictionary<string, object>
最佳答案
看起来你在这里真正做的是比较手动装箱和内置装箱。内置的装箱已经过高度优化 - 所以我不希望在这里看到巨大的差异,但我们可以检查一下。重要的是,请注意两者具有相同的内存影响:一个堆对象包含一个 int
字段,每个 int
装箱/包装。
以下显示了两个接近的时间几乎相同;因此,我会说,只需以直接/内置的方式将其装箱即可。
注意:在 Release模式下运行它,没有调试器(最好在命令行)。请注意,第一个调用是预先 JIT 一切。
using System;
using System.Diagnostics;
public sealed class IntObj
{
public readonly int Value;
public IntObj(int value)
{
Value = value;
}
}
static class Program
{
static void Main()
{
Run(1, 0, false);
Run(100000, 500, true);
Console.ReadKey();
}
static void Run(int length, int repeat, bool report)
{
var data = new object[length];
int chk = 0;
var watch = Stopwatch.StartNew();
for (int j = 0; j < repeat; j++)
{
for (int i = 0; i < data.Length; i++)
{
data[i] = i;
chk += i;
}
}
watch.Stop();
if(report) Console.WriteLine("Box: {0}ms (chk: {1})", watch.ElapsedMilliseconds, chk);
chk = 0;
watch = Stopwatch.StartNew();
for (int j = 0; j < repeat; j++)
{
for (int i = 0; i < data.Length; i++)
{
chk += (int) data[i];
}
}
watch.Stop();
if (report) Console.WriteLine("Unbox: {0}ms (chk: {1})", watch.ElapsedMilliseconds, chk);
chk = 0;
watch = Stopwatch.StartNew();
for (int j = 0; j < repeat; j++)
{
for (int i = 0; i < data.Length; i++)
{
data[i] = new IntObj(i);
chk += i;
}
}
watch.Stop();
if (report) Console.WriteLine("Wrap: {0}ms (chk: {1})", watch.ElapsedMilliseconds, chk);
chk = 0;
watch = Stopwatch.StartNew();
for (int j = 0; j < repeat; j++)
{
for (int i = 0; i < data.Length; i++)
{
chk += ((IntObj)data[i]).Value;
}
}
watch.Stop();
if (report) Console.WriteLine("Unwrap: {0}ms (chk: {1})", watch.ElapsedMilliseconds, chk);
}
}
关于c# - .NET 装箱/拆箱与类型转换性能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12294655/