Модераторы: Partizan, gambit

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Интересная статья, о производительности в .NET 
:(
    Опции темы
Experimenter
Дата 7.11.2007, 13:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 430
Регистрация: 8.5.2007
Где: Уфа

Репутация: 8
Всего: 17



Вот такую статью нарыл

Честно скажу, оставила она у меня двоякое впечатление.
С одной стороны, дотнет как человеку, который с него и начал, дал мне почву для творчества на многие годы. Как технология безусловно интересная, новая и почти всемогущая. Тем более, что дотнет сейчас меня кормит.
С другой стороны постепенно начинаю ощущать легкое разочарование. К чему тогда все это бесчисленное количество возможностей, если от него производительность страдает? Плюнуть на эти возможности и ограничиться элементарными операциями, к которым сводятся перегруженные методы в .NET? Или не заморачиваться над этим, никто ж с секундомером возле моей программы не стоит? И к чему мелкие нас готовят дальше, чтоб любой, не только программист, смог открыть студию, накидать на форму контролов, выставить им свойства и создать прогу для своих потребностей без единой строчки самописного кода, и неважно, что там в памяти твориться будет?

В общем, слушаю ваши мнения, а также может у кого ссылки есть, как не надо писать код.


--------------------
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"); }
PM WWW ICQ   Вверх
0000
Дата 7.11.2007, 15:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 208
Регистрация: 11.7.2006
Где: Нижний Новгород

Репутация: 2
Всего: 5



любопытная статейка...я где-то раньше подобные встречал..
для меня на данный момент вопрос производительности важен, поскольку большинство своих разработок сейчас веду под Compact Framework и Windows Mobile, а тут с производительностью туго...

если вцелом, думаю проблема действительно важная, поскольку MS хочет сделать программирование для пользователей, а не для программистов...одна у них цель - побольше народу заманить этим и денег соответственно

все имхо

ЗЫ. пасиба за статью, закрою еще пару тормозничков в работе  smile 
PM MAIL ICQ   Вверх
Experimenter
Дата 7.11.2007, 15:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 430
Регистрация: 8.5.2007
Где: Уфа

Репутация: 8
Всего: 17



Вот еще фишка, документирована она или нет, неизвестно, нашел у Троелсена.
Раньше без всякой задней мысли использовал код:
Код

string s = "First Word";
s += " Second Word";

Так вот, говорит Троелсен, всякое такое присоединение строк приводит к созданию в памяти копии первоначальной строки, к которой прибавляется уже " Second Word". Первичное же значение ожидает сборки мусора. Если работаешь со строками небольшой величины, то это как бы и неактуально. А если выполнить присоединение 1000 раз, еще и строчки длинные? Поэтому, говорит Троелсен, используйте StringBuilder, он и только он работает непосредственно со строкой в буфере. Для меня это было откровением, может и еще кто не знает этого.


--------------------
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"); }
PM WWW ICQ   Вверх
altarvic
Дата 7.11.2007, 15:53 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 87
Регистрация: 2.3.2007

Репутация: 1
Всего: 1



По этому поводу читайте Рихтера и MSDN'овские статьи типа "CLR Inside" 
Откровений будет много smile
Не думаю что простые юзеры будут способны на большее чем "Хеллоу Ворлд!"
Тенденция идет к разделению процессов написания кода и рисования интерфейса, причем и там  и там без проффессиональной подготовки врядли чего-то можно добиться. У дотнета своя ниша на рынке, там где нужны быстрые алгоритмы и скорость - C++
PM MAIL   Вверх
Wizard_Memfis
Дата 7.11.2007, 16:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 193
Регистрация: 12.2.2007
Где: г. Донецк, Украин а

Репутация: 1
Всего: 4



Согласен 
Цитата

У дотнета своя ниша на рынке, там где нужны быстрые алгоритмы и скорость - C++

C# - прежде всего быстрая и довольно качественная реализация поставленной задачи!
--------------------
www.binary-studio.com
PM MAIL WWW ICQ Skype   Вверх
thomas
Дата 7.11.2007, 16:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Доцент... почти
***


Профиль
Группа: Завсегдатай
Сообщений: 1385
Регистрация: 3.10.2006
Где: " Сказочное королевство"

Репутация: 6
Всего: 65



Неплохо.
Мне например хочеться сказать, что многое зависит от того как учат программировать.
Если препод в школе Ас, то он нормально преподает и рассказывает что как и почему нужно делать, а потом на примерах использования для решения тех или иных конкретных задач показывает плюсы и минусы того или иного действа. Плюс подробный разбор полетов после выполнения домашних заданий.  Но таких преподов мало. Не зря говорят: "все познается в сравнении". 

А статья полезная.

Добавлено через 7 минут и 47 секунд
В связи вспомнился анектод про методы оперирования гланд.
"типа на международном медицинском конгрессе после того как западные светилы рассказали о каких-то умопомрачительных и супер сложных методиках проведения операций на сердце или мозг,некие отечественные спецы заявили о том, что они разработали новый метод оперирования гланд - через анальное отверстие и афтогеном"

К чему это? Каждую задачу можно решить тремя способами:
- нормально;
- оптимально;
- и через одно место.
Для первого надо представлять как это работает.
Для второго иметь креативное мышление и ОЧЕНЬ хорошо представлять как это работает.
Ну а третье и так понятно, знаний точно не хватает.


--------------------
Крепко жму горло, искренне ваш Thomas. (С)vingrad
Некоторые сорта флоры буквально за одно мгновение превращают нас в фауну!
Проблемы негров шерифа не волнуют.
PM MAIL   Вверх
Baa
Дата 7.11.2007, 16:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 2639
Регистрация: 12.4.2002
Где: Москва

Репутация: 1
Всего: 12



Цитата(Experimenter @ 7.11.2007,  15:17)
Вот еще фишка, документирована она или нет, неизвестно, нашел у Троелсена.
Раньше без всякой задней мысли использовал код:
Код

string s = "First Word";
s += " Second Word";

Документирована, конечно, более того, встречается на сертификационных экзаменах MS.
Все дело в том, что string immutable (Хотя на самом деле это не совсем так и через unsafe он меняется ;-) ). 
Даже простая фигня вроде s = s.Replace ("bla", "lab") ведет к созданию новой строки smile
MS рекомендует использовать StringBuilder, String.Join, String.Format.


Это сообщение отредактировал(а) Baa - 7.11.2007, 16:40


--------------------
"Duty is everything; the greatest of joys, the deepest of sorrows" Aribeth de Tylmarande
PM ICQ   Вверх
archeg
Дата 7.11.2007, 16:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 612
Регистрация: 6.1.2007
Где: Киев

Репутация: 11
Всего: 27



Да, согласен, это немного обидно то что .нет работает не всегда так быстро как бы хотелось, но каждый программист выбирает свое. Иногда нужно чем-то пожертвовать ради таких удобств как автоматическая сборка мусора. Может быть мне так легко об этом говорить, поскольку я практически никогда не работал с другой сборкой мусора  smile Но многие статьи меня напугали и я не хочу работать с другой smile 

Статья кажись хорошая. Еще не дочитал - времени не много, но вечером обязательно прочту.

П.С. Хорошего профа по шарпу я представляю себе как такого человека, что может написать офигенно ясный, функциональный и быстрый код. Именно в таком порядке - сначало ясный, потом функц. а потом уже быстрый. Профа по спп я себе представляю как человека который может написать офигенно быстрый и функциональный код. То же именно в таком порядке. И вряд ли он будет ясный  smile 

П.П.С. Вся эта фигня со стрингами, как нистранно сделана для скорости и для економии памяти. Расчитано на то что програмист должен понимать разницу между стрингами и стринг билдером. Простой стринг - он интернованый. То есть два одинаковых стринга в памяти на самом деле есть один объект. По этому его просто нельзя менять - это приведет к непередвиденным результатам. То есть создав:
Код

string s1 = "Hello world!";
string s2 = "Hello world!";

Получим два указателя на одну область памяти где хранится "Hello world!" Конечно же все это документировано и большинство авторов обращают на это внимание. Советую почитать Рихтера, у него привычка говорить не просто "что" а еще и "как" и "почему" - что намного интересней, и для меня именно это критерий профа.

Это сообщение отредактировал(а) archeg - 7.11.2007, 16:52


--------------------
ИМХО задница есть универсальный интерфейс. Ибо через задницу можно сделать абсолютно ВСЕ (bash.org.ru)

Дядька всегда можно спросить в аське, если не задалбывать - не откажет smile
И вообще, на самом деле я студент, и ненавижу обращение на "Вы") Тут все свои  ;)
PM MAIL ICQ Jabber   Вверх
Baa
Дата 7.11.2007, 16:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 2639
Регистрация: 12.4.2002
Где: Москва

Репутация: 1
Всего: 12



А по поводу концепции упрощения интерфейсов, так всё дело в том, что сейчас сроки на разработку программного обеспечения становятся всё меньше и меньше. Единственный способ успевать всё вовремя - иметь хорошую библиотеку классов, чего Майкрософт и старается сделать. Как-то было рассуждение на их форуме, мол, .NET не дает достаточной скорости для общения с COM портом, так этому человеку ответили, что для этого есть С++, а C# нужня для быстрой разработки "корпоративных" приложений.
Сейчас, как и раньше, необходимо правильно выбирать инструмент. Если вы хотите быстроты и 100% контроля, то выбирайте С++, а если хотите делать всё быстро, то тогда C#.


--------------------
"Duty is everything; the greatest of joys, the deepest of sorrows" Aribeth de Tylmarande
PM ICQ   Вверх
Experimenter
Дата 7.11.2007, 18:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 430
Регистрация: 8.5.2007
Где: Уфа

Репутация: 8
Всего: 17



Да, Рихтера осваиваю понемногу, когда время есть.
Цитата

Не думаю что простые юзеры будут способны на большее чем "Хеллоу Ворлд!"

Думаю, что будут способны, когда кодинг уподобится процессу записи макросов в МС Офис.

Добавлено через 9 минут и 38 секунд
Вообще благодаря классам-заготовкам .NET успеваешь очень много сделать. Ну а с производительностью - в принципе тоже есть время позаниматься, проанализировать, так сказать - ювелирно довести опять же благодаря тому, что много успел раньше. Но - появился резон засесть за С++. Эх, где на все время найти...


--------------------
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"); }
PM WWW ICQ   Вверх
thomas
Дата 7.11.2007, 18:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Доцент... почти
***


Профиль
Группа: Завсегдатай
Сообщений: 1385
Регистрация: 3.10.2006
Где: " Сказочное королевство"

Репутация: 6
Всего: 65



Experimenter
Цитата

Думаю, что будут способны

Не а.
Посмотри на темы в Базах данных.
Многие когда используют дизайнер для датасет потом задают много вопросов а почему то, а почему сё. Потому как студия сама генерит код, а "программер" не понимает какие процессы происходят или должны происходить за кулисами дизайнера чтобы программа показывала нужные данные в нужном месте или при выборе одного в другом месте показывалось ему соответствующее, да еще и сохранялось в БД при изменении. ИМХО

Добавлено через 5 минут и 9 секунд
Цитата

 Но - появился резон засесть за С++. Эх, где на все время найти...

Я бы предпочел, "поглубжее" вникнуть как работает C# и VB в .NET.Лучше быть специалистом в узкой области, чем ...(нужное подставте сами) широкого профиля. 


Это сообщение отредактировал(а) thomas - 7.11.2007, 18:48


--------------------
Крепко жму горло, искренне ваш Thomas. (С)vingrad
Некоторые сорта флоры буквально за одно мгновение превращают нас в фауну!
Проблемы негров шерифа не волнуют.
PM MAIL   Вверх
Experimenter
Дата 7.11.2007, 19:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 430
Регистрация: 8.5.2007
Где: Уфа

Репутация: 8
Всего: 17



thomas
Цитата

Я бы предпочел, "поглубжее" вникнуть как работает C# и VB в .NET
тоже верно, но нужда заставляет, не то чтобы производительность не устраивала или еще что-то, но вот нужна сейчас библиотека на Си-шарп, работающая с СОМ-приложениями, а без понимания принципов их работы никак. Так что почитываю, заинтересовался. А так конечно, куда ж я без дотнета. Это хлеб мой!
У нас был один такой кадр на работе, сыпал терминами и определениями из ИТ-технологий и программирования так что можно было червяком себя почувствовать, а как до дела дошло - код написал ни к черту, глюк на глюке, баг на баге... Короче, уволился он через три месяца, так ничего и не создав.


--------------------
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"); }
PM WWW ICQ   Вверх
tol05
Дата 7.11.2007, 19:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1632
Регистрация: 21.12.2006
Где: Харьков

Репутация: 63
Всего: 170



Цитата(archeg @  7.11.2007,  15:46 Найти цитируемый пост)
Хорошего профа по шарпу я представляю себе как такого человека, что может написать офигенно ясный, функциональный и быстрый код. Именно в таком порядке - сначало ясный, потом функц. а потом уже быстрый. Профа по спп я себе представляю как человека который может написать офигенно быстрый и функциональный код. То же именно в таком порядке. И вряд ли он будет ясный 


а я себе представляю так: 

хороший программер - себе код педалит и тебе педалит. И он, и ты - при деньгах

плохой программер - педалит только себе, причем много и хорошо. Он - при деньгах, а ты - в ... (нужное вставить по желанию)

злой программер - педалит себе, как плохой, но и тебе подпедаливает. Посылает, правда, тебя постоянно в ... и на ... (нужное вставить по желанию), но на жизнь тебе хватает.

smile


--------------------
На хорошей работе и сны хорошие снятся.
PM MAIL   Вверх
1stain
Дата 7.11.2007, 19:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 486
Регистрация: 30.7.2007
Где: Киев - Харьков

Репутация: 8
Всего: 40



статья приколная, только по-моему с сериализацией аффтар слегка загнался.

tol05, у тебя так не хороший программер получается, а глупый программер, который педалит себе и ленивому или тупому программеру.


--------------------
Все знают, что это невозможно. Но вот приходит невежда, которому это неизвестно - он-то и делает открытие. (Albert Einstein)
user posted image
PM MAIL   Вверх
archeg
Дата 7.11.2007, 20:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 612
Регистрация: 6.1.2007
Где: Киев

Репутация: 11
Всего: 27



На работе игрался с тестом там где форич и фор - как то у меня вышло что фор заработал медленее форича (или может мне показалось?). Повторить не удалось smile

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

З.Ы. Скорость работы не всегда решает  smile 


--------------------
ИМХО задница есть универсальный интерфейс. Ибо через задницу можно сделать абсолютно ВСЕ (bash.org.ru)

Дядька всегда можно спросить в аське, если не задалбывать - не откажет smile
И вообще, на самом деле я студент, и ненавижу обращение на "Вы") Тут все свои  ;)
PM MAIL ICQ Jabber   Вверх
Experimenter
Дата 7.11.2007, 21:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 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"); }
PM WWW ICQ   Вверх
archeg
Дата 7.11.2007, 21:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 612
Регистрация: 6.1.2007
Где: Киев

Репутация: 11
Всего: 27



Цитата(Experimenter @  7.11.2007,  21:04 Найти цитируемый пост)
Чего кричат-то? про форич и фор? 

Нет, я про всю статью... В общем что-то типа: "плевать на скорость, хочу удобства в написании кода и функционала"  smile 


--------------------
ИМХО задница есть универсальный интерфейс. Ибо через задницу можно сделать абсолютно ВСЕ (bash.org.ru)

Дядька всегда можно спросить в аське, если не задалбывать - не откажет smile
И вообще, на самом деле я студент, и ненавижу обращение на "Вы") Тут все свои  ;)
PM MAIL ICQ Jabber   Вверх
stab
Дата 8.11.2007, 14:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Экс. модератор
Сообщений: 1839
Регистрация: 1.1.2003

Репутация: 22
Всего: 48



Цитата(archeg @  7.11.2007,  20:46 Найти цитируемый пост)
Простой стринг - он интернованый.

Только строковые константы\литералы, остальные интернируются только при явном указании String.Intern, что делать без очень большой необходимости не надо, т.к. после вызова этого метода строка останется в памяти до выгрузки домена из памяти, даже если на неё нет больше ссылок в коде. Нет способа удалить её из пула интернированных строк.

Про статью:

1. Перечисления. Автор двоечник и мерил скорость выполнения пустого цикла, компилер выкидывает такое тело, в этом может убедиться каждый, воспользовавшись рефлектором. Я на месте компилера ещё бы и сам цикл выкидывал. Даже если автор отключил оптимизацию, то джитер всё равно тело цикла выкинет:

Код

0000000c    xor        edx,edx 
0000000e    jmp        00000013 
00000010    add        edx,1 
00000013    cmp        edx,989680h 
00000019    setl       al   
0000001c    movzx      eax,al 
0000001f    test       eax,eax 
00000021    jne        00000010


Как можно заметить, цикл пуст. -1 автору smile Правда не очень понятно почему джитер такой странный код использует для проверки на завершение цикла, почему сразу после проверки не делается jne 00000010 - большая загадка. Плюс к этому, код явно создаёт ложную зависимость по EAX, что может сильно сказаться на производительности во многих случаях. -1 джитеру.

Со своей стороны могу предложить в какой-то степени некрасивый код для честного теста оригинального метода и того, что используется мной:

Код

class Program
{
    private const uint Iterations = 100000000;

    static void Main(string[] args)
    {
        bool taskStoped = false;
        Stopwatch watch = new Stopwatch();

        TaskStatus status = 0;
        watch.Start();
        for (uint i = 0; i < Iterations; i++)
        {
            taskStoped = (status & TaskStatus.Stoped) == TaskStatus.Stoped;
            status++;
        }
        watch.Stop();
        Console.WriteLine("1: {0} ms, {1}", watch.ElapsedMilliseconds, taskStoped);

        // --

        status = 0;
        watch.Reset();
        watch.Start();
        for (uint i = 0; i < Iterations; i++)
        {
            taskStoped = (status & TaskStatus.Stoped) != 0;
            status++;
        }
        watch.Stop();
        Console.WriteLine("2: {0} ms, {1}", watch.ElapsedMilliseconds, taskStoped);

        Console.ReadLine();
    }
}

238 ms
176 ms

Мой способ короче в записи и немного быстрее. В любом случае, другие два описанных метода - жуткое убожество разума. -1 MVP, +1 автору smile

2. Циклы. Тут вроде всё по уму протестировано, но почему-то у меня разница на инициализации не 10 раз, а 4.

3. Объектно-ориентированное программирование. Бредовое, имхо, тестирование, виртуальные члены не инлайнятся, а статические инлайнятся в данном случае, т.к. объём кода мал, но, по данным со спутников-шпионов, для членов объёмом более 32-х байт в IL это не так. А вообще-то, автор опять тестирует пустой цикл для не виртуальных членов. -1 автору smile Кроме того, виртуальные и статические члены имеют разную логику работы и применяются для разных целей. Честное тестирование не должно использовать инлайн и должно иметь "switch" при вызове статических членов - доморощенный полиморфизм.

Без инлайна, т.к. это наиболее вероятный вариант, например если метод выкидывает исключения, то, на данный момент, он не инлайнится, из-за того, что начинаются проблемы с раскруткой стека в случае исключений. Так же, у меня есть подозрения, если код использует методы типов, которые могут кидать исключения, то инлайн так же отключается.  Таким образом, в более-менее серьёзном проекте каждый второй статический метод не инлайнится. Со "switch", т.к. это полностью реализует функциональность виртуальных членов - грубо говоря, "switch" по типу:

Код

class Program
{
    private const uint Iterations = 100000000;

    static void Main(string[] args)
    {
        Stopwatch watch = new Stopwatch();


        watch.Start();
        for (uint i = 0; i < Iterations; i++)
        {
            Static.DoWork1(i);
        }
        watch.Stop();
        Console.WriteLine("static: {0} ms", watch.ElapsedMilliseconds);

        bool callDoWork1 = true;
        watch.Reset();
        watch.Start();
        for (uint i = 0; i < Iterations; i++)
        {
            if (callDoWork1)
            {
                Static.DoWork1(i);
            }
            else
            {
                Static.DoWork2(i);
            }
            callDoWork1 = !callDoWork1;
        }
        watch.Stop();
        Console.WriteLine("static \"polymorphic\": {0} ms", watch.ElapsedMilliseconds);

        watch.Reset();
        watch.Start();
        AbstractBase obj = new Virtual2();
        for (uint i = 0; i < Iterations; i++)
        {
            obj.DoWork(i);
        }
        watch.Stop();
        Console.WriteLine("virtual: {0} ms", watch.ElapsedMilliseconds);


        Console.ReadLine();
    }

    public static class Static
    {
        [MethodImpl(MethodImplOptions.NoInlining)]
        public static int DoWork1(uint value)
        {
            if (value == uint.MaxValue)
            {
                return 0;
            }
            else
            {
                return 1;
            }
        }

        [MethodImpl(MethodImplOptions.NoInlining)]
        public static int DoWork2(uint value)
        {
            if (value == uint.MaxValue)
            {
                return 0;
            }
            else
            {
                return 1;
            }
        }
    }
}

public abstract class AbstractBase
{
    public abstract int DoWork(uint value);
}

public class Virtual1: AbstractBase
{
    public override int DoWork(uint value)
    {
        throw new InvalidOperationException();
    }
}

public class Virtual2: Virtual1
{
    public override int DoWork(uint value)
    {
        if (value == uint.MaxValue)
        {
            return 0;
        }
        else
        {
            return 1;
        }
    }
}

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, это выглядит куда более элегантней, избавляет от лишней писанины и к тому же не проигрывает по скорости, т.к. инлайнится.

Короче, автор двоечник. smile И подвело его банальное не понимание того, что только пустой цикл в 10 000 000 итераций может выполняться за 8 миллисекунд.


--------------------
6, 6, 6 - the number of the beast.
PM MAIL WWW   Вверх
Experimenter
Дата 8.11.2007, 15:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 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"); }
PM WWW ICQ   Вверх
stab
Дата 8.11.2007, 15:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Экс. модератор
Сообщений: 1839
Регистрация: 1.1.2003

Репутация: 22
Всего: 48



Цитата(Experimenter @  8.11.2007,  19:25 Найти цитируемый пост)
Но крупицы истины все-таки в статье есть. 

Да, есть.. немного, особенно там, где статья не касается собственно оптимизации, а касается хорошего стиля написания кода. Но в целом, работа выглядит искусственной. Сомневаюсь, что автор не знал об агрессивной оптимизации в простейших случаях, когда комилятор/джитер может статически просчитать довольно сложные вычисления.


--------------------
6, 6, 6 - the number of the beast.
PM MAIL WWW   Вверх
Experimenter
Дата 8.11.2007, 17:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 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"); }
PM WWW ICQ   Вверх
stab
Дата 9.11.2007, 12:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Экс. модератор
Сообщений: 1839
Регистрация: 1.1.2003

Репутация: 22
Всего: 48



Есть два уровня оптимизации:

1. Компилятор. Выкидывает из кода вещи которые никогда не сработают или результат работы которых нигде не используется, иногда сопровождает это варнингами, иногда нет. Например:

Код

if (Math.PI == 1.0)
{
    Console.WriteLine("OMG, Pi = 1.0");
}

Выдаст Unreachable code detected, в сборке просто не будет этого if и его тела.

Код

for (int i = 0; i < 100; i++)
{
    int sum = i + i;
}

Тут никаких сообщений не будет, но тело цикла будет пустым в сборке. Сам цикл оставляют видимо из-за того, что есть такая штука как busy-waiting loops. Хотя, честно говоря, я не очень понимаю зачем это делается - может просто страшно удалить полностью. smile

В общем, компилятор осуществляет статические подстановки и вычисляет значения выражений заранее, там где это возможно. Так же, отслеживает используется ли результат работы такого или иного выражения или его побочные эффекты (side effects) в дальнейшей работе.  На основе этого выкидывает код или заменяет его на более простой. Никаких более глобальных оптимизаций не делается, этим занимается джитер.

2. Джитер. Тут начинается самое интересное. Как всем известно, джитер занимается переводом IL-кода в машинный, заявлено, что делает он это учитывая особенности процессора на котором всё это осуществляется. На самом деле, довольно сложно наткнуться на такой специализированный код, по большей части расширенные инструкции применяются для копирования больших структур и работы с Int64 и Double, да и то очень редко. Ни о какой автоматической векторизации вычислений даже речи не идёт, а жаль.

Вся сила джитера, на данный момент, в инлайне. Например:

Код

Console.WriteLine(Divide(4, 2));

static int Divide(int dividend, int divisor)
{
    if (divisor == 0)
    {
        throw new ArgumentOutOfRangeException("divisor");
    }
    else
    {
        return dividend / divisor;
    }
}

После обработки джитером это будет просто Console.WriteLine(2), т.е. джитер статически вычислил значение Divide(4, 2) и заменил его на результат - 2. Во многих случаях он этого конечно не сможет сделать, например если бы я получал параметры Divide с консоли, то этого бы не произошло. Вывод: джитеру надо помогать. smile Как можно меньше исключений, как можно меньший объём кода, как можно меньше динамики.


--------------------
6, 6, 6 - the number of the beast.
PM MAIL WWW   Вверх
Experimenter
Дата 9.11.2007, 12:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 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"); }
PM WWW ICQ   Вверх
stab
Дата 9.11.2007, 13:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Экс. модератор
Сообщений: 1839
Регистрация: 1.1.2003

Репутация: 22
Всего: 48



.. забыл упомянуть один тонкий момент. В последнем примере, если бы не было выброса исключения ArgumentOutOfRangeException и было бы динамическое чтение параметров с консоли, то джитер заинлайнил бы машинный код метода Divide перед вызовом Console.WriteLine, но так как метод может выбросить исключение, этого не происходит.


--------------------
6, 6, 6 - the number of the beast.
PM MAIL WWW   Вверх
Страницы: (2) [Все] 1 2 
Ответ в темуСоздание новой темы Создание опроса
Прежде чем создать тему, посмотрите сюда:
mr.DUDA
THandle

Используйте теги [code=csharp][/code] для подсветки кода. Используйтe чекбокс "транслит" если у Вас нет русских шрифтов.
Что делать если Вам помогли, но отблагодарить помощника плюсом в репутацию Вы не можете(не хватает сообщений)? Пишите сюда, или отправляйте репорт. Поставим :)
Так же не забывайте отмечать свой вопрос решенным, если он таковым является :)


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, mr.DUDA, THandle.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Общие вопросы по .NET и C# | Следующая тема »


 




[ Время генерации скрипта: 0.1531 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.