在 C# 中,将 int(或任何值类型)存储为对象并将它们转换回 int(或值类型)是否有任何成本?
基本上我需要创建一个内存表。我可以为每种可能的类型创建特定的“列”(因此任何原始值类型,如 int、double、string 等,以及我想存储在表中的用户定义的引用类型,如 Order)或者我可以简单地将所有内容存储为一个对象并在访问表时将它们转换回正确的类型。
所以我的问题是哪种方法会表现更好或两者都相同?
或者我应该为所有值类型坚持使用特定的“列”并将所有用户定义的引用类型存储为对象?
谢谢 - 下面的示例代码 - 静态测试方法显示用法。
public sealed class Columns
{
public static void Test()
{
Columns cols = new Columns(100);
cols.SetInt(0,Int_Column,12345);
int value = cols.GetInt(0,Int_Column);
cols.SetObject(1,Object_Column,12345);
int value2 = (int)cols.GetObject(1,Object_Column);
}
private const int Int_Column = 0;
private const int String_Column = 1;
private const int Object_Column = 2;
private int[] _intCol;
private string[] _stringCol;
private object[] _objCol;
public Columns(int rowCount)
{
_intCol = new int[rowCount];
_stringCol = new string[rowCount];
_objCol = new object[rowCount];
}
public void SetInt(int rowIndex, int colIndex, int value)
{
switch(colIndex)
{
case Int_Column:
_intCol[rowIndex] = value;
break;
default:
throw new Exception("Incorrect column index specified.");
}
}
public int GetInt(int rowIndex, int colIndex)
{
switch(colIndex)
{
case Int_Column:
return _intCol[rowIndex];
default:
throw new Exception("Incorrect column index specified.");
}
}
public void SetString(int rowIndex, int colIndex, string value)
{
switch(colIndex)
{
case String_Column:
_stringCol[rowIndex] = value;
break;
default:
throw new Exception("Incorrect column index specified.");
}
}
public string GetString(int rowIndex, int colIndex)
{
switch(colIndex)
{
case String_Column:
return _stringCol[rowIndex];
default:
throw new Exception("Incorrect column index specified.");
}
}
public void SetObject(int rowIndex, int colIndex, object value)
{
switch(colIndex)
{
case Object_Column:
_objCol[rowIndex] = value;
break;
default:
throw new Exception("Incorrect column index specified.");
}
}
public object GetObject(int rowIndex, int colIndex)
{
switch(colIndex)
{
case Object_Column:
return _objCol[rowIndex];
default:
throw new Exception("Incorrect column index specified.");
}
}
}
最佳答案
这称为装箱,在性能和内存使用方面的成本实际上是巨大的。如果您想避免装箱,并且想让一些简单类型(如 int 和 double)共享内存,请使用 LayoutKind struct layout attribute强制他们共享内存,然后将您的列表设置为该结构类型。例如:
[StructLayout(LayoutKind.Explicit)]
[CLSCompliant(false)]
public struct NumberStackEntry
{
/// <summary>Type of entry</summary>
[FieldOffset(0)]
public EntryTypes entryType;
/// <summary>Value if double</summary>
[FieldOffset(4)]
public double dval;
/// <summary>Value if ulong</summary>
[FieldOffset(4)]
public ulong uval;
/// <summary>Value if long</summary>
[FieldOffset(4)]
public long lval;
/// <summary>Value if integer</summary>
[FieldOffset(4)]
public int ival;
}
编辑:您可以创建一个包含上述内容的数组,而无需装箱以使用这些值填充数组的成员。但是,您不能将数组添加到结构中,并使其与非 CLI 引用类型共享内存。
关于c# - 将 int(或任何值类型)存储为对象并将它们转换回 int(或值类型)是否有任何成本?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6752942/