.net - Get unsafe pointer to array of KeyValuePair<DateTime,decimal> in C# -
i have big arrays of keyvaluepair<datetime,decimal>
. know in memory array contiguous since kvp value type, datetime int64, , decimal array of 4 ints (and won't change). however, datetime not blittable, , decimal not primitive.
is there any way abuse type system , unsafe pointer array , work bytes? (gchandle.alloc
cannot work these 2 types when part of structure, works ok arrays of type.)
(if interested why, convert array manually believe 1-to-1 byte[] representation, , slow)
finally, there public tool: system.runtime.compilerservices.unsafe package.
below passing test:
using system.runtime.compilerservices.unsafe; [test] public unsafe void couldusenewunsafepackage() { var dt = new keyvaluepair<datetime, decimal>[2]; dt[0] = new keyvaluepair<datetime, decimal>(datetime.utcnow.date, 123.456m); dt[1] = new keyvaluepair<datetime, decimal>(datetime.utcnow.date.adddays(1), 789.101m); var obj = (object)dt; byte[] asbytes = unsafe.as<byte[]>(obj); //console.writeline(asbytes.length); // prints 2 fixed (byte* ptr = &asbytes[0]) { // reading this: https://github.com/dotnet/coreclr/issues/5870 // looks fix byte[] , keyvaluepair<datetime, decimal> fixed // because: // "gc not care exact types, e.g. if type of local object // reference variable not compatible stored in it, // gc still track fine." (int = 0; < (8 + 16) * 2; i++) { console.writeline(*(ptr + i)); } var firstdate = *(datetime*)ptr; assert.areequal(datetime.utcnow.date, firstdate); console.writeline(firstdate); var firstdecimal = *(decimal*)(ptr + 8); assert.areequal(123.456m, firstdecimal); console.writeline(firstdecimal); var seconddate = *(datetime*)(ptr + 8 + 16); assert.areequal(datetime.utcnow.date.adddays(1), seconddate); console.writeline(seconddate); var seconddecimal = *(decimal*)(ptr + 8 + 16 + 8); assert.areequal(789.101m, seconddecimal); console.writeline(seconddecimal); } }
Comments
Post a Comment