Извините за запутанное название, но я не могу придумать лучшего способа объяснить это.Почему BitConverter.ToInt32 читает один байт за раз, если данные не выровнены по заданному смещению?
При просмотре the source code из BitConverter
недавно я наткнулся на странный сегмент кода:
public static unsafe int ToInt32(byte[] value, int startIndex)
{
fixed (byte* pbyte = &value[startIndex])
{
if (startIndex % 4 == 0) // data is aligned
return *((int*)pbyte);
else
{
if (IsLittleEndian)
{
return (*pbyte) | (*(pbyte + 1) << 8) | (*(pbyte + 2) << 16) | (*(pbyte + 3) << 24);
}
else
{
return (*pbyte << 24) | (*(pbyte + 1) << 16) | (*(pbyte + 2) << 8) | (*(pbyte + 3));
}
}
}
}
Как литья pbyte
к int*
(строка 6) нарушают выравнивание данных в этом случае? Я оставил его для краткости, но код имеет правильную проверку аргументов, поэтому я уверен, что это не может быть нарушение доступа к памяти. Означает ли он точность при бросании?
Другими словами, почему не может код быть упрощена:
public static unsafe int ToInt32(byte[] value, int startIndex)
{
fixed (byte* pbyte = &value[startIndex])
{
return *(int*)pbyte;
}
}
Edit:Here это раздел кода в вопросе.
Операции с данными, выровненными на границе размера данных, выполняются быстрее, а на некоторых процессорах доступ к неприсоединенным словам/dwords/float/doubles - это доступность доступа (комментарий, так как у меня нет хорошей ссылки). –
@AlexeiLevenkov Тем не менее, вы создаете две дополнительные ветви, несколько побитовых операций, * и * разыменование 'pbyte + 1',' pbyte + 2' и т. Д. (3 из которых не будут выровнены), чтобы вы могли избегайте этого неприсоединения. Кажется, это довольно переполняет меня. –
Не уверен в вашем комментарии - есть процессоры, которые вы не можете получить без выравнивания 'int' - http://stackoverflow.com/questions/1237963/alignment-along-4-byte-boundaries - так какая альтернативная реализация вы предлагаете по сравнению с чтением байт по байт? –