статья "Сравнительное тестирование пяти способов сравнить байтовые массивы в C#"
От: Философ Ад http://vk.com/id10256428
Дата: 18.03.14 20:55
Оценка: 11 (2)
В результате профилирования моей софтины была установлена необходимость оптимизации функции сравнения буферов. CRL не предоставляет стандартного способа сравнить два куска памяти, и функция была написан на скорую руку самостоятельно — я решил погуглить.
Набрал в поисковике «Best Way to Compare Byte Arrays in .Net» и прошёлся по результатам. Поразительно, но в абсолютном большинстве случаев люди предлагали использовать либо LINQ, либо Enumerable.SequenceEqual(), что практически одно и тоже. Даже на SO это был самый популярный ответ. Т.е. катастрофически популярно заблуждение вида:

Compiler\run-time environment will optimize your loop so you don't need to worry about performance.

вот отсюда

Именно оно привело к идее написать сабжевую статью.


В статье произведено сравнительное тестирование пяти методов сравнения буферов, доступных из C#, по результатам которого даны рекомендации в выборе того или иного метода. Декомпилированы отдельные функции, и проанализирован код, генерируемый JIT-компилятором для конфигурации x86. Произведено сравнение машинного кода, генерируемого JIT-компилятором, с машинным кодом функции CRT аналогичного назначения.


статья здесь
Автор(ы): Харченко Андрей Владимирович
Дата: 18.03.2014
Произведено сравнительное тестирование пяти методов сравнения буферов, доступных из C#, по результатам которого даны рекомеднации в выборе того или иного метода. Декомпилированы отдельные функции, и проанализирован код, генериуемый .Net JIT-компилятором для конфигурации x86. Произведено сравнение машинного кода, генерируемого JIT-компилятором с кодом, машинным кодом функции CRT аналогичного назначения.


обсуждение статьи здесь
Автор: Kupaev
Дата: 18.03.14
Всё сказанное выше — личное мнение, если не указано обратное.
Re: статья "Сравнительное тестирование пяти способов сравнить байтовые массивы в
От: nikov США http://www.linkedin.com/in/nikov
Дата: 18.03.14 21:27
Оценка: 3 (1)
Здравствуйте, Философ, Вы писали:

Ф>В статье произведено сравнительное тестирование пяти методов сравнения буферов, доступных из C#, по результатам которого даны рекомендации в выборе того или иного метода. Декомпилированы отдельные функции, и проанализирован код, генерируемый JIT-компилятором для конфигурации x86. Произведено сравнение машинного кода, генерируемого JIT-компилятором, с машинным кодом функции CRT аналогичного назначения.


По-моему, у тебя какие-то совершенно фантастические ожидания от JIT в отношении оптимизаций. Фактически, ты хочешь, чтобы он по коду распознавал замысел программиста, и самостоятельно сочинял самый оптимальный код, который выполнит ту же задачу.

По поводу вызова memcmp через PInvoke, насколько я понимаю, у тебя при маршалинге будет происходить копирование массивов, переданных в качестве аргументов.
Re[2]: статья "Сравнительное тестирование пяти способов сравнить байтовые массив
От: Философ Ад http://vk.com/id10256428
Дата: 19.03.14 00:23
Оценка:
Здравствуйте, nikov, Вы писали:

N>Здравствуйте, Философ, Вы писали:


Ф>>В статье произведено сравнительное тестирование пяти методов сравнения буферов, доступных из C#, по результатам которого даны рекомендации в выборе того или иного метода. Декомпилированы отдельные функции, и проанализирован код, генерируемый JIT-компилятором для конфигурации x86. Произведено сравнение машинного кода, генерируемого JIT-компилятором, с машинным кодом функции CRT аналогичного назначения.


N>По-моему, у тебя какие-то совершенно фантастические ожидания от JIT в отношении оптимизаций. Фактически, ты хочешь, чтобы он по коду распознавал замысел программиста, и самостоятельно сочинял самый оптимальный код, который выполнит ту же задачу.


Нет, я никаких иллюзий не испытываю на этот счёт, но я видел достаточно много людей, которые верят во всемогущество JIT'тера.
Эта статья изначально задумывалась как пост на хабр, и предназначалась как раз для них.
Даже тут (на кывте), где-то в священных войнах я видел несколько заблуждений на эту тему.


N>По поводу вызова memcmp через PInvoke, насколько я понимаю, у тебя при маршалинге будет происходить копирование массивов, переданных в качестве аргументов.


Похоже, что это не так. Во-первых, потому что байтовый массив это blittable-тип (затрудняюсь перевести), а во-вторых это было бы сразу видно из времени выполнения: на больших массивах время было бы в 2 или больше раз больше, чем для unsafe (операции с памятью в этом процессе — самые медленные).
К тому же в логе трассировки этого не видно.

Most data types have a common representation in both managed and unmanaged memory and do not require special handling by the interop marshaler. These types are called blittable types because they do not require conversion when passed between managed and unmanaged code.
The following types from the System namespace are blittable types:
System.Byte
System.SByte
System.Int16
System.UInt16
System.Int32
System.UInt32
System.Int64
System.IntPtr
System.UIntPtr
The following complex types are also blittable types:
One-dimensional arrays of blittable types, such as an array of integers.
Formatted value types that contain only blittable types (and classes if they are marshaled as formatted types).

As an optimization, arrays of blittable types and classes containing only blittable members are pinned instead of copied during marshaling. These types can appear to be marshaled as In/Out parameters when the caller and callee are in the same apartment. However, these types are actually marshaled as In parameters and you must apply the InAttribute and OutAttribute attributes if you want to marshal the argument as an In/Out parameter.

http://msdn.microsoft.com/en-us/library/aa719791(v=vs.71).aspx
Всё сказанное выше — личное мнение, если не указано обратное.
Re[3]: статья "Сравнительное тестирование пяти способов сравнить байтовые массив
От: nikov США http://www.linkedin.com/in/nikov
Дата: 19.03.14 01:25
Оценка:
Здравствуйте, Философ, Вы писали:

N>>По поводу вызова memcmp через PInvoke, насколько я понимаю, у тебя при маршалинге будет происходить копирование массивов, переданных в качестве аргументов.


Ф>Похоже, что это не так. Во-первых, потому что байтовый массив это blittable-тип (затрудняюсь перевести), а во-вторых это было бы сразу видно из времени выполнения: на больших массивах время было бы в 2 или больше раз больше, чем для unsafe (операции с памятью в этом процессе — самые медленные).


Действительно, я был неправ.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.