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

Jonathan Shore jonathan.shore at gmail.com
Fri Nov 18 07:21:48 EST 2011


I'm not sure what you mean.  The BitConverter class takes in bytes in the native endianess of the machine.   This should work on a sparc as as well as an intel computer, though the byte[] orders going in would be reversed.    Perhaps there are concerns with non-word aligned conversions on some architectures?

If this is a "can of worms" and needs to be arch specific, will leave as is for now.   I can only test on little endian machines which have no alignment issues.

On Nov 18, 2011, at 1:57 AM, Rodrigo Kumpera wrote:

> This would not work on little endian machines, so some changes would be needed.
> 
> On Thu, Nov 17, 2011 at 11:44 PM, Jonathan Shore <jonathan.shore at gmail.com> wrote:
> 
> 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
> 
> 
> 
> _______________________________________________
> Mono-devel-list mailing list
> Mono-devel-list at lists.ximian.com
> http://lists.ximian.com/mailman/listinfo/mono-devel-list
> 
> 

-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.ximian.com/pipermail/mono-devel-list/attachments/20111118/632363d9/attachment-0001.html 


More information about the Mono-devel-list mailing list