[Mono-dev] implementation of BitConverter [possible perf improvements?]

Jonathan Shore jonathan.shore at gmail.com
Thu Nov 17 23:44:35 EST 2011


I was looking at the code for the mono implementation of BitConverter and was surprised to see that common types (such as long) are converted by writing to a byte* a byte at a time.   I don't  know why it was done this way unless this was done to avoid a temporary pin of the byte[].

The current code is:

		unsafe static void PutBytes (byte *dst, byte[] src, int start_index, int count)
		{
			if (src == null)
				throw new ArgumentNullException ("value");

			if (start_index < 0 || (start_index > src.Length - 1))
				throw new ArgumentOutOfRangeException ("startIndex", "Index was"
					+ " out of range. Must be non-negative and less than the"
					+ " size of the collection.");

			// avoid integer overflow (with large pos/neg start_index values)
			if (src.Length - count < start_index)
				throw new ArgumentException ("Destination array is not long"
					+ " enough to copy all the items in the collection."
					+ " Check array index and length.");

			for (int i = 0; i < count; i++)
				dst[i] = src[i + start_index];
		}

		unsafe public static long ToInt64 (byte[] value, int startIndex)
		{
			long ret;

			PutBytes ((byte *) &ret, value, startIndex, 8);

			return ret;
		}



The above code does avoid pinning the byte[] buffer, however is 3-4x slower than, say doing this:

		unsafe public static long ToLong (byte[] buffer, int offset)
		{
			fixed (byte* pbuf = buffer)
			{
				long* vlong = (long*)(pbuf + offset);
				return *vlong;
			}
		}


Any reason why we would not want to do the above?

Jonathan


-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.ximian.com/pipermail/mono-devel-list/attachments/20111117/170a4d4a/attachment-0001.html 


More information about the Mono-devel-list mailing list