我不习惯使用指针(例如 C++)或不安全的孤岛进行编码:仅使用“安全”C#。 现在我想在 C# 中为 .Net Micro Framework 实现一个函数,其中紧凑性和性能非常重要。 基本上,我会收集 4 条短裤,从而填充缓冲区(例如字节数组)。 假设每个样本都是这样的:
struct MyStruct
{
public short An1;
public short An2;
public short An3;
public short An4;
}
每个样本都是通过计时器事件收集的,因此我无法循环(有几个原因)。 我尝试了很多方法来有效地做到这一点,但表现最好的似乎是这个:
unsafe struct MyStruct2
{
public fixed byte Buffer[Program.BufferSize];
}
unsafe class Program
{
public const int BufferSize = 0x1000;
public const int ArraySize = BufferSize / 8;
static MyStruct2 _struct2 = new MyStruct2();
static MyStruct* _structPtr;
unsafe static void Main(string[] args)
{
int iter = 5000; //just for simulate many cycles
for (int i = 0; i < iter; i++)
{
//let's make a trick!
fixed (byte* ptr = _struct2.Buffer)
_structPtr = (MyStruct*)ptr;
_structIndex = 0;
do
{
Test5();
} while (++_structIndex < ArraySize);
}
Console.ReadKey();
}
unsafe static void Test5()
{
_structPtr->An1 = (short)An1();
_structPtr->An2 = (short)An2();
_structPtr->An3 = (short)An3();
_structPtr->An4 = (short)An4();
_structPtr++;
}
//simulations of ADC reading
static int An1()
{
return 0x1111;
}
static int An2()
{
return 0x2222;
}
static int An3()
{
return 0x3333;
}
static int An4()
{
return 0x4444;
}
}
相对于以下这种更安全的方式的改进 - 例如 - 不是那么高(177 毫秒对 224 毫秒),但无论如何它都很重要。
static MyStruct Test3()
{
var data = new MyStruct();
data.An1 = (short)An1();
data.An2 = (short)An2();
data.An3 = (short)An3();
data.An4 = (short)An4();
return data;
}
注意:我删减了一些代码,但我觉得已经够清楚了。
我的问题是:我通过将“固定”指针复制到另一个未固定指针而做出的“技巧”是否可靠?...但是您可以假设所有数据都是静态分配的,因此应该固定。 先感谢您。 干杯
最佳答案
我认为代码不安全。在固定范围内的 _structPtr = (MyStruct*)ptr
之后,假设 _struct2 不会移动,您可以继续将数据放入 _structPtr 中。虽然您认为它不会被 GC 是正确的,但这并不意味着 GC 不会在内存压缩期间移动它。 .NET Compact Framework 仍在进行垃圾收集,我认为它会压缩内存而不是让内存碎片化。
例如,如果在 _struct2 之前在堆上分配的临时(非静态)对象被 GC 删除,则该结构使用的内存可能会转移到该临时对象使用的可用空间中。此时 _structPtr 指向未使用的内存。
修改 Test3() 以获取 ref MyStruct 数据
会有帮助吗?
此外,检查 [StructLayout(LayoutKind.Explicit)]
和 [FieldOffset(...)]
这将允许您拥有一个具有多种方式的结构访问其中的相同数据。在您的情况下,可以是 4 个字节或 1 个 int 或(可能)1 个 4 字节数组。
关于c# - 提高速度的不安全 C# 技巧,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5302153/