|
Модераторы: Partizan, gambit |
|
Experimenter |
|
|||
Опытный Профиль Группа: Участник Сообщений: 430 Регистрация: 8.5.2007 Где: Уфа Репутация: 8 Всего: 17 |
archeg,
-------------------- public Zlo FromTwoEvilsChooseSmaller(Zlo zlo1, Zlo zlo2){ if(zlo1 < zlo2) return zlo1; else if(zlo1 > zlo2) return zlo2; else throw new Exception("Kill yourself by the wall"); } |
|||
|
||||
archeg |
|
|||
Опытный Профиль Группа: Участник Сообщений: 612 Регистрация: 6.1.2007 Где: Киев Репутация: 11 Всего: 27 |
Нет, я про всю статью... В общем что-то типа: "плевать на скорость, хочу удобства в написании кода и функционала" -------------------- ИМХО задница есть универсальный интерфейс. Ибо через задницу можно сделать абсолютно ВСЕ (bash.org.ru) Дядька всегда можно спросить в аське, если не задалбывать - не откажет И вообще, на самом деле я студент, и ненавижу обращение на "Вы") Тут все свои ;) |
|||
|
||||
stab |
|
||||||
Эксперт Профиль Группа: Экс. модератор Сообщений: 1839 Регистрация: 1.1.2003 Репутация: 22 Всего: 48 |
Только строковые константы\литералы, остальные интернируются только при явном указании String.Intern, что делать без очень большой необходимости не надо, т.к. после вызова этого метода строка останется в памяти до выгрузки домена из памяти, даже если на неё нет больше ссылок в коде. Нет способа удалить её из пула интернированных строк. Про статью: 1. Перечисления. Автор двоечник и мерил скорость выполнения пустого цикла, компилер выкидывает такое тело, в этом может убедиться каждый, воспользовавшись рефлектором. Я на месте компилера ещё бы и сам цикл выкидывал. Даже если автор отключил оптимизацию, то джитер всё равно тело цикла выкинет:
Как можно заметить, цикл пуст. -1 автору Правда не очень понятно почему джитер такой странный код использует для проверки на завершение цикла, почему сразу после проверки не делается jne 00000010 - большая загадка. Плюс к этому, код явно создаёт ложную зависимость по EAX, что может сильно сказаться на производительности во многих случаях. -1 джитеру. Со своей стороны могу предложить в какой-то степени некрасивый код для честного теста оригинального метода и того, что используется мной:
238 ms 176 ms Мой способ короче в записи и немного быстрее. В любом случае, другие два описанных метода - жуткое убожество разума. -1 MVP, +1 автору 2. Циклы. Тут вроде всё по уму протестировано, но почему-то у меня разница на инициализации не 10 раз, а 4. 3. Объектно-ориентированное программирование. Бредовое, имхо, тестирование, виртуальные члены не инлайнятся, а статические инлайнятся в данном случае, т.к. объём кода мал, но, по данным со спутников-шпионов, для членов объёмом более 32-х байт в IL это не так. А вообще-то, автор опять тестирует пустой цикл для не виртуальных членов. -1 автору Кроме того, виртуальные и статические члены имеют разную логику работы и применяются для разных целей. Честное тестирование не должно использовать инлайн и должно иметь "switch" при вызове статических членов - доморощенный полиморфизм. Без инлайна, т.к. это наиболее вероятный вариант, например если метод выкидывает исключения, то, на данный момент, он не инлайнится, из-за того, что начинаются проблемы с раскруткой стека в случае исключений. Так же, у меня есть подозрения, если код использует методы типов, которые могут кидать исключения, то инлайн так же отключается. Таким образом, в более-менее серьёзном проекте каждый второй статический метод не инлайнится. Со "switch", т.к. это полностью реализует функциональность виртуальных членов - грубо говоря, "switch" по типу:
static: 655 ms static "polymorphic": 728 ms virtual: 619 ms Остальное тестировать просто не интересно, instance call = static call + this в ECX, interface call = virtual call, но немного медленней, видимо, из-за специфической инстукции в которую он в конечном счёте превращается, abstract call = virtual call, вообще не понимаю почему автор в отдельный тест его вынес. Автор явно лукавит на счёт интерфейсов, не может быть такой разницы: 929 - интерфейсы - call dword ptr ds:[00930010h] 669 - виртуальные члены - call dword ptr [eax+38h] У меня разница всего в 10 миллисекунд. Закрадывается вопрос, на чём же тестировал автор? 4. Файловые операции. Как это водится, всё свелось к ограничению функциональности, мог бы хотя бы знаменитый RSDN-овский бинарный форматер в пример привести, его хотя бы можно приспособить для обмена SOAP-сообщениями и не только. "Remouting сделан для облегчения разработки клиент-серверных решений. По сути, он заменяет TCP/IP." - позабавило, как можно заменить протоколом из Application Layer протоколы из Transport Layer и Network Layer. 5. Инициализация классов. Для начинающих полезно. +1 6. Сравнение типов. И опять автор тестирует пустые циклы, все выражения в if первых двух циклов просто вырезаются при компиляции. Честное тестирование на объекте предварительно приведенном к object даёт цифры в 10 раз большие. И опять же, typeof немного другой функционал предоставляет, иногда нужно узнать точный тип, а не возможность приведения. 7. Проверка на инициализацию строки. Проверку на инициализацию строки надо делать с помощью String.IsNullOrEmpty, это выглядит куда более элегантней, избавляет от лишней писанины и к тому же не проигрывает по скорости, т.к. инлайнится. Короче, автор двоечник. И подвело его банальное не понимание того, что только пустой цикл в 10 000 000 итераций может выполняться за 8 миллисекунд. -------------------- 6, 6, 6 - the number of the beast. |
||||||
|
|||||||
Experimenter |
|
|||
Опытный Профиль Группа: Участник Сообщений: 430 Регистрация: 8.5.2007 Где: Уфа Репутация: 8 Всего: 17 |
stab, прекрасно, не поленился, проверил, не то что я и многие тут на слово поверили аффтару.
+1 Но крупицы истины все-таки в статье есть. -------------------- public Zlo FromTwoEvilsChooseSmaller(Zlo zlo1, Zlo zlo2){ if(zlo1 < zlo2) return zlo1; else if(zlo1 > zlo2) return zlo2; else throw new Exception("Kill yourself by the wall"); } |
|||
|
||||
stab |
|
|||
Эксперт Профиль Группа: Экс. модератор Сообщений: 1839 Регистрация: 1.1.2003 Репутация: 22 Всего: 48 |
Да, есть.. немного, особенно там, где статья не касается собственно оптимизации, а касается хорошего стиля написания кода. Но в целом, работа выглядит искусственной. Сомневаюсь, что автор не знал об агрессивной оптимизации в простейших случаях, когда комилятор/джитер может статически просчитать довольно сложные вычисления. -------------------- 6, 6, 6 - the number of the beast. |
|||
|
||||
Experimenter |
|
|||
Опытный Профиль Группа: Участник Сообщений: 430 Регистрация: 8.5.2007 Где: Уфа Репутация: 8 Всего: 17 |
А можно об этом чуть поподробнее? -------------------- public Zlo FromTwoEvilsChooseSmaller(Zlo zlo1, Zlo zlo2){ if(zlo1 < zlo2) return zlo1; else if(zlo1 > zlo2) return zlo2; else throw new Exception("Kill yourself by the wall"); } |
|||
|
||||
stab |
|
||||||
Эксперт Профиль Группа: Экс. модератор Сообщений: 1839 Регистрация: 1.1.2003 Репутация: 22 Всего: 48 |
Есть два уровня оптимизации:
1. Компилятор. Выкидывает из кода вещи которые никогда не сработают или результат работы которых нигде не используется, иногда сопровождает это варнингами, иногда нет. Например:
Выдаст Unreachable code detected, в сборке просто не будет этого if и его тела.
Тут никаких сообщений не будет, но тело цикла будет пустым в сборке. Сам цикл оставляют видимо из-за того, что есть такая штука как busy-waiting loops. Хотя, честно говоря, я не очень понимаю зачем это делается - может просто страшно удалить полностью. В общем, компилятор осуществляет статические подстановки и вычисляет значения выражений заранее, там где это возможно. Так же, отслеживает используется ли результат работы такого или иного выражения или его побочные эффекты (side effects) в дальнейшей работе. На основе этого выкидывает код или заменяет его на более простой. Никаких более глобальных оптимизаций не делается, этим занимается джитер. 2. Джитер. Тут начинается самое интересное. Как всем известно, джитер занимается переводом IL-кода в машинный, заявлено, что делает он это учитывая особенности процессора на котором всё это осуществляется. На самом деле, довольно сложно наткнуться на такой специализированный код, по большей части расширенные инструкции применяются для копирования больших структур и работы с Int64 и Double, да и то очень редко. Ни о какой автоматической векторизации вычислений даже речи не идёт, а жаль. Вся сила джитера, на данный момент, в инлайне. Например:
После обработки джитером это будет просто Console.WriteLine(2), т.е. джитер статически вычислил значение Divide(4, 2) и заменил его на результат - 2. Во многих случаях он этого конечно не сможет сделать, например если бы я получал параметры Divide с консоли, то этого бы не произошло. Вывод: джитеру надо помогать. Как можно меньше исключений, как можно меньший объём кода, как можно меньше динамики. -------------------- 6, 6, 6 - the number of the beast. |
||||||
|
|||||||
Experimenter |
|
|||
Опытный Профиль Группа: Участник Сообщений: 430 Регистрация: 8.5.2007 Где: Уфа Репутация: 8 Всего: 17 |
stab, удовлетворен ответом на все 100
-------------------- public Zlo FromTwoEvilsChooseSmaller(Zlo zlo1, Zlo zlo2){ if(zlo1 < zlo2) return zlo1; else if(zlo1 > zlo2) return zlo2; else throw new Exception("Kill yourself by the wall"); } |
|||
|
||||
stab |
|
|||
Эксперт Профиль Группа: Экс. модератор Сообщений: 1839 Регистрация: 1.1.2003 Репутация: 22 Всего: 48 |
.. забыл упомянуть один тонкий момент. В последнем примере, если бы не было выброса исключения ArgumentOutOfRangeException и было бы динамическое чтение параметров с консоли, то джитер заинлайнил бы машинный код метода Divide перед вызовом Console.WriteLine, но так как метод может выбросить исключение, этого не происходит.
-------------------- 6, 6, 6 - the number of the beast. |
|||
|
||||
Прежде чем создать тему, посмотрите сюда: | |
|
Используйте теги [code=csharp][/code] для подсветки кода. Используйтe чекбокс "транслит" если у Вас нет русских шрифтов. Что делать если Вам помогли, но отблагодарить помощника плюсом в репутацию Вы не можете(не хватает сообщений)? Пишите сюда, или отправляйте репорт. Поставим :) Так же не забывайте отмечать свой вопрос решенным, если он таковым является :) Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, mr.DUDA, THandle. |
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
0 Пользователей: | |
« Предыдущая тема | Общие вопросы по .NET и C# | Следующая тема » |
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |