IntPtr is a
struct and so by default is passed by value, this might be expensive (as new object is created every time) and so we better pass it by reference when new object is not mandatory. For example I wrote such code (please ignore hardcoded "magic numbers"):
public static DateTime IntPtrToDateTime(ref IntPtr value, int offset)
short year = Marshal.ReadInt16(value, offset);
byte month = Marshal.ReadByte(value, offset + 2);
byte day = Marshal.ReadByte(value, offset + 3);
byte hour = Marshal.ReadByte(value, offset + 4);
byte minute = Marshal.ReadByte(value, offset + 5);
byte second = Marshal.ReadByte(value, offset + 6);
short msec = Marshal.ReadInt16(value, offset + 8);
return new DateTime(year, month, day, hour, minute, second, msec);
Works fine, but I'm doubt if I really should pass IntPtr by reference? I guess
IntPtr struct is very "light" and likely very easy to create.
Marshal class in .NET framework passes
IntPtr by value, for example Marshal.ReadInt64 I guess
Marshal class is designed to be the lowest-possible latency, but why
IntPtr is not passed by reference then?
No, you shouldn't pass it by reference. That will only cause more overhead in the code in this case.
As it's a structure the size of a pointer, passing it by value and by reference will put the same amount of data on the stack, and it will be about the same amount of work to put it on the stack.
Using a parameter passed by reference will however cause another level of indirection. Instead of reading the value from the stack you will be reading a pointer from the stack and then reading the value using the pointer.
Also, semantially you should only use
out for parameters where you actually want to change the variable used to pass the value.
If you have a large structure that you want to pass by reference for performance reasons, then it's actually the large structure in itself that is causing the performance issues, not how you pass it as a parameter. You should make it a class rather than changing how you pass it.
Structs are passed by value and there is no new heap object allocated for them. Also, IntPtr is a type natively understood by the CLR. It is the size of a single pointer. You should expect the same performance profile as you can expect from an
long (depending on your bitness).
Passing it by reference will slow things down because you wrap a pointer with a pointer.