Здравствуйте, vdimas, Вы писали:
I>>>>"прирост до 50 раз " @ vdimas
V>>>Этот множитель сложился из двух множимых. См. исходный пост на русском языке: http://www.rsdn.ru/forum/philosophy/4843592.1.aspxАвтор: vdimas
Дата: 05.08.12
.
I>>То есть, ты разницу между IList и List помножил на разницу между ручной и встроеной серилизацией ?
V>Наоборот, разделил общий эффект на разницу м/у ручной и встроенной сериализацией, чтобы получить прирост от тупой замены абстрактных типов на конкретные.
То есть во фразе "множитель сложился из двух множимых" слово "сложился" надо понимать как произведение, но при этом надо делить ?
I>>Итого, максимальная разница между List и IList в 2.5 раза. С valuetype вместо object разница еще меньше, всего 1.5 раза.
I>>Вероятно "от 3-х до ~10-ти" ты получил вообще на пустых итерациях
V>Итого, у тебя опять работает заведомо синтетика и заведомо некорректная.
V>Даю тебе вторую попытку. Вместо 10КК прогонов по циклу попробуй прогон по десяткам элементов (это ближе к реальной задаче сериализации разветвленного графа объекта в памяти), а внешний цикл пусть будет 10КК/x, где x — кол-во элементов.
V>Сразу получишь более 3-х раз разницы (у меня — 3.75).
Никакого "сразу" быть не может. Время колеблется от прогона к прогону, что для дотнета вобщем то норма.
Вот результаты 10 прогонов двух тестов — total(for IList<>)/total(for List<>)
4.0 3.5 2.0 2.5 2.7 2.9 2.3 2.4 2.9 2.3
Дальше мне стало лень
>Ну а потом погоняй стоимость вызова других методов, например стоимость обращения к элементу по индексу (иначе нахрена именно IList??).
Стоимость обращения к элементу по индексу в принципе не может зависеть от длины списка что собственно и показывают результаты.
V>В общем, более 8-ми раз на реальных задачах выходила разница из-за простой замены IList<> на конкретные типы. По приведенной ссылке — результаты с реального проекта.
После твоих "уточнений" я всерьез думаю ты или попутал результаты(массив вместо List и тд) или просто сочиняешь, выбирай сам.
V>Думаю, более корректным будет тест с глубиной вложенности объектов хотя бы 2. Т.е. было бы неплохо сделать коллекцию в коллекции, разбив эти 100 элементов хотя бы 10*10.
Это ни о чем. Эффект появится только в двумерном выравненом массиве и никак не в списке.
I>>Объясняю — использование List может быть очень дорогим удовольствием, а хочется, что бы некоторые функции вроде Linq2Objects работали крайне быстро, выход — IList<>
V>Это не объяснение, а туманность Андромеды. Покажи, где IList<> будет быстрее List<>.
Это очень просто, IList<> может иметь любую реализацию, т.е. оптимизация под конкретные сценарии, не любые а именно те что нужны. У меня вот нет ручной серилизации
Смотри внимательно, моя реализация IList
Contains O(N/K)
IndexOf O(N/K + K/4)
Remove — O(N/K)
RemoveAt — O(N/K + K/4)
RemoveAt(0) — O(1) для сравнения List имеет здесь O(N), что в линейном алгоритме даёт O(N^^2) — очень жОсткое ограничение, т.е. просто так использовать практически никак
Дополнительно моя реализация никогда не попадёт в LOH, например это проявляется в том, что в GC вызывается примерно на порядок реже и прога не валится от OOM после получаса зависания в GC.
В сумме это примерно так — операции которые педалили по 6 часов и более теперь укладываются в 5 минут, а время отклика UI уменьшилось в среднем в 10 раз.
V>>>Дык, никто не мешает использовать любые конкретные типы, в т.ч. обычный массив. И таки, если речь об итерировании, то итерирование по List<> нифига не дорогое удовольствие, в отличие от IList<>.
I>>Ты похоже не понимаешь — если List это очень дорого, то и массив тоже будет так же дорого.
V>Да, пока что не понимаю, пока ты не показал, где IList<> будет быстрее List<>.
Вероятно ты IList<> понимаешь исключительно как ((IList<>)List<>)
I>>Реальная разница в 2.5 раза на почти пустой итерации. Если цикл чуть сложнее суммы элементов, эта разница становится ничтожной.
V>Для задач просто чтения элементов, о которой речь в сериализации, разница оказалась катастрофической. При десериализации тоже тоже оказалась в несколько раз, бо при десериализации используются те самые остальные методы интерфейса List/IList для наполнения коллекций.
Чушь, разница в добавлении от силы в 10% в вырожденых случаях.
Инлайн дает эффект только тогда, если тело метода тривиальное. Добавление "тяжелая" операция — раскрой метод тулом и посмотри, ты сэкономишь ровно один виртуальный вызов, что для Add вообще ничего. Скажем Array.Resize в сумме съест намного больше.