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

Rodrigo Kumpera kumpera at gmail.com
Fri Nov 18 18:17:46 EST 2011


Alignment is one of those issues but, yes, you're right that it's meant to
handle native endianness.
This is, on itself, another issue that it's not relevant here.

Handling alignment is tricky since it requires runtime support.



On Fri, Nov 18, 2011 at 7:21 AM, Jonathan Shore <jonathan.shore at gmail.com>wrote:

> 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/70dc2ff2/attachment-0001.html 


More information about the Mono-devel-list mailing list