I just saw these go by on an internal alias and thought i'd share them with you...

Recommendation: If you control the interface between managed and unmanaged code, make it "chunky" rather than "chatty," to reduce the total number of transitions made.

Chatty interfaces are interfaces that make a lot of transitions without doing any significant work on the other side.  For example, property setters and getters are chatty.  Chunky interfaces are interfaces that make only a few transitions and work done on the other side is significant.  For example, method that opens a database connection and retrieves some data is chunky.  Chunky interfaces involve fewer interop transitions, so you eliminate overhead.

 

Recommendation: Avoid Unicode/ANSI conversions if possible.

Converting strings from Unicode to ANSI and vice versa is an expensive operation.  For example, if some strings need to be passed but their content is not important you can declare parameter as IntPtr and interop marhaler won’t do any conversions.

 

Recommendation: For high-performance scenarios, declaring parameters and fields as IntPtr can boost performance (at the expense of ease-of-use and maintainability).

Sometimes it is faster to do manual marshaling using methods available on the Marshal class then rely on default interop marshaling.  For example, if large arrays of strings need to be passed across interop boundary but only few elements will be needed, declaring array as IntPtr and accessing only those few elements manually will be much faster.

 

Recommendation: Using InAttribute and OutAttribute wisely can reduce unnecessary marshaling.

Interop marhaler will use default rules when deciding if some parameter needs to be marshaled in before the call and out after the call.  These rules are based on level of indirection and type of parameter. Some of these operations might not be necessary depending on the method’s semantics.

 

Recommendation: Use SetLastError=false on PInvoke signatures if you're not going to call Marshal.GetLastWin32Error afterward.

Setting SetLastError=true on PInvoke signatures will require some additional work from interop layer to preserve last error code.  Use this only when you rely on this information and will use it after the call is made.

 

Recommendation: If (and only if) unmanaged calls are exposed in a non-exploitable fashion, use SuppressUnmanagedCodeSecurityAttribute to reduce number of security checks.

Security checks are very important.  They will make sure that nobody can misuse your API.  Sometimes your API doesn’t expose any protected resources/sensitive information or they are well protected. In those situations extensive security checks might introduce unnecessary overhead.