Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>I am going to answer my own question. I realize that this is bad style, but I could not have formulated the answer if it were not for the wonderful resources that previous answers have supplied me. Thank you.</p> <p>First off, those coming here and wondering how to, in general, inspect the innards of C# functions, Tim posted a wonderful resource, <a href="http://wiki.sharpdevelop.net/ILSpy.ashx" rel="nofollow">ILSpy</a>. This works in the cases where the methods are not defined externally. When they are defined externally, it seems like the only hope for getting an answer is if you download the <a href="http://www.microsoft.com/en-us/download/details.aspx?id=4917" rel="nofollow">SSCLI 2.0</a>. Since this is targeted for .Net 2.0 and not 4.0, the information I present may be dated. However, I will continue with the assumption that the methods in question have not changed much. After looking through the source files, I believe I can answer the question “does Array.CopyTo call Buffer.BlockCopy behind the scenes?”</p> <p>Before I get to the heart of the matter, others have pointed out that CopyTo calls Array.Copy. Array.Copy is defined externally, so I will change my query to “does Array.Copy call Buffer.BlockCopy behind the scenes?” A little tidbit that I found interesting is from the <a href="http://msdn.microsoft.com/en-us/library/06x742cw.aspx" rel="nofollow">documentation of Array.CopyTo on MSDN</a></p> <blockquote> <p>If implementing System.Collections.ICollection is not explicitly required, use [Array.]Copy to avoid an extra indirection.</p> </blockquote> <p>Let me distinguish the types of checks that must be true for each function to perform:</p> <p>BlockCopy:</p> <ol> <li>Destination and Source cannot be null</li> <li>Destination and Source array are composed of primitives or strings but no objects.</li> <li>The lengths and offsets must be valid</li> </ol> <p>Array.Copy:</p> <ol> <li>Destination and Source cannot be null</li> <li>Destination and Source must be an array</li> <li>Several checks with method tables and ranks</li> <li>Slightly more in-depth length and offset checks</li> <li>Types must match somehow (either with un/boxing, casting, or widening)</li> </ol> <p>After these checks, BlockCopy calls m_memmove, which is self-explanatory, yet highly interesting. m_memmove is architecture dependent; forgoing traditional memmove on 32-bit machines in favor for a hand rolled 16 bytes at a time copy.</p> <p>Arrays, as can be imagined, hold more than just primitives. </p> <ul> <li>If the source and destination array are of the same type, Copy calls m_memmove. Then, if the underlying type is not a primitive, a garbage collection action is enacted.</li> <li>Else, depending on the type of elements passed in, Copy will unbox, box, cast, or widen each element as it transfers them. These functions, as far as I can tell, do not call m_memmove, and instead convert each element one at a time. </li> </ul> <p>Therefore, to answer my original question, “does Array.Copy call Buffer.BlockCopy behind the scenes?” Sort of, if we consider the similarities the two methods have in common dealing with m_memmove. BlockCopy will always call m_memmove whereas Copy will only call it if it is dealing with arrays of exactly the same type. It is then my recommendation, if one wanted to copy an array of bytes to ints, or something similar where they just cared about the raw data, to use BlockCopy as it will be able to take advantage of m_memmove.</p> <p>For reference: what .Net defines as a primitive (taken from cortypeinfo.h) </p> <ol> <li>Void</li> <li>Bool</li> <li>Char</li> <li>Signed and Unsigned Byte</li> <li>Signed and Unsigned short</li> <li>Signed and Unsigned int</li> <li>Signed and Unsigned long</li> <li>Float and double</li> <li>Signed and Unsigned IntPtr</li> <li>ELEMENT_TYPE_R (not sure what this is)</li> </ol>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload