Здравствуйте, ·, Вы писали:
_>>Да всем понятно как тут и что решается. Если мы пишем дохленький сайтик на .net с парой посетителей в день, то всем глубоко наплевать на этот оверхед, т.к. он никогда не почувствуется. А если ты делаешь на .net (что правда является сомнительной идей на мой вкус, ну да ладно) высоконагруженный сервис с тысячами запросов в секунду или какое-то реалтаймовое решение, в котором актуальны миллисекунды, то просто все эти EF и ему подобные решения на базе Linq выкидываются на помойку и пишется в старых добрых традициях обычный sql код. ·>Да зря ты так. В теории, конечно всё так, но на практике... ·>Во-первых, реалтаймовое решение с миллисекундным уровнем не может использовать субд, по крайней мере обычную. ·>Во-вторых, рефлеския обычно таки быстра, время явно микросекунды, а то и наносекунды. Играет ли это хоть какую-то заментую роль при доступе к БД, где только пинг как минимум 5ms? А возьми тот же rsdn или stackoverflow и время рисования странички ~100ms, получится что эта рефлексия составляет доли процента. ·>В-третьих, без показаний профайлера разговоры о производительности — как минимум непрофессиональны.
Не стоит недооценивать тормоза linq. ))) Ну давай посмотрим на мнение профессионалов с профайлерами:
И это кстати всё фанаты .net и linq, а не какие-то там нехорошие C++ники. ))) Просто они в отличие от большинства пользователей .net встречались с реализацией действительно нагруженных систем.
Здравствуйте, Serginio1, Вы писали:
_>>Да всем понятно как тут и что решается. Если мы пишем дохленький сайтик на .net с парой посетителей в день, то всем глубоко наплевать на этот оверхед, т.к. он никогда не почувствуется. А если ты делаешь на .net (что правда является сомнительной идей на мой вкус, ну да ладно) высоконагруженный сервис с тысячами запросов в секунду или какое-то реалтаймовое решение, в котором актуальны миллисекунды, то просто все эти EF и ему подобные решения на базе Linq выкидываются на помойку и пишется в старых добрых традициях обычный sql код. S> Давай считать. Как ты думаешь чему равно время рефлексии, передаче данных между процессами, парсинг текста SQL. S>Вообще когда говорят от тысячами запросов в секунду на современных компьютерах то это вызывает смех.
См. сообщение выше.
S>Для примера вызов нетовского метода из 1С через Ireflect составляет на моем старом ноутбуке 20 000 вызовов в секунду. S>http://infostart.ru/public/448668/
50 мкс? Жутко много (это же сотни тысяч ассемблерных инструкций!). Ну и при построение sql из linq будут десятки обращение к рефлексии.
Здравствуйте, alex_public, Вы писали:
_>И это кстати всё фанаты .net и linq, а не какие-то там нехорошие C++ники. ))) Просто они в отличие от большинства пользователей .net встречались с реализацией действительно нагруженных систем.
В принципе согласен, что могут быть ситуации, когда тормоза начинают становиться значительными, но если это происходит относительно редко — это не повод отказываться от технологии. Скажем, compile-time тоже бесплатно не даётся. Сутки компиляции C++-шаблонов тоже может стать препятствием использования "zero-overhead".
В общем, баланс. Инь-янь. И всё такое.
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
S>>Для примера вызов нетовского метода из 1С через Ireflect составляет на моем старом ноутбуке 20 000 вызовов в секунду. S>>http://infostart.ru/public/448668/
_>50 мкс? Жутко много (это же сотни тысяч ассемблерных инструкций!). Ну и при построение sql из linq будут десятки обращение к рефлексии.
Угу это вызов из интерпритатора. Упаковка и распаковка данных между манагед и унманагед кодом и на древнем ноутбуке.
Да еще внутри куча вызовов.
public object InvokeMember(string name, System.Reflection.BindingFlags invokeAttr, System.Reflection.Binder binder, object target, object[] argsOrig, System.Reflection.ParameterModifier[] modifiers, System.Globalization.CultureInfo culture, string[] namedParameters)
{ // Unwrap any AutoWrap'd objects (they need to be raw if a paramater)if (name == "[DISPID=-4]")
{
IEnumVARIANT rez = new EnumVariantImpl(((System.Collections.IEnumerable)O).GetEnumerator());
return rez;
}
object[] args = ПолучитьМассивРеальныхОбъектов(argsOrig);
culture = CultureInfo.InvariantCulture;
// Invoke whatever needs be invoked!object obj;
try
{
if (T.IsEnum && !((invokeAttr & BindingFlags.InvokeMethod) == BindingFlags.InvokeMethod))
return ОбернутьОбъект(Enum.Parse(T, name));
// if (ЭтоСемерка)
ПроверитьНаДоступКПолям(ref invokeAttr, args.Length);
if (ЭтоТип)
obj = T.InvokeMember(name, invokeAttr, binder, null, args, modifiers, culture, namedParameters);
else if (ЭтоExpandoObject)
{
if (invokeAttr.HasFlag(BindingFlags.InvokeMethod) && МетодыObject.ContainsKey(name))
obj = T.InvokeMember(name, invokeAttr, binder, O, args, modifiers, culture, namedParameters);
else
obj = InvokeMemberExpandoObject(name, invokeAttr, args);
}
else
obj = T.InvokeMember(name, invokeAttr, binder, O, args, modifiers, culture, namedParameters);
}
catch (Exception e)
{
ПоследняяОшибка = e;
string Ошибка = "Ошибка в методе " + name + " " + e.Message + " " + e.Source;
if (e.InnerException != null)
Ошибка = Ошибка + "\r\n" + e.InnerException.ToString();
if (ВыводитьСообщениеОбОшибке)
{
MessageBox.Show(Ошибка);
MessageBox.Show(e.StackTrace);
MessageBox.Show(invokeAttr.ToString());
}
throw new COMException(Ошибка);
}
// Так как параметры могут изменяться (OUT) и передаются по ссылке
// нужно обратно обернуть параметры
УстановитьИзмененияВМассиве(argsOrig, args);
return ОбернутьОбъект(obj);
}
Ты кстати перед заявлениями делай проверки и пиши уже с реальными данными
и солнце б утром не вставало, когда бы не было меня
Здравствуйте, alex_public, Вы писали:
_>50 мкс? Жутко много (это же сотни тысяч ассемблерных инструкций!). Ну и при построение sql из linq будут десятки обращение к рефлексии.
Вот здесь так вообще низенько, но летает 10m вызовов за ~3s http://jeremybytes.blogspot.com/2014/01/improving-reflection-performance-with.html Всего лишь в 10 раз медленнее обычного вызова.
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Здравствуйте, alex_public, Вы писали:
I>>Если не веришь, создай дефолтный проект дотнет бизнес веб-приложения в вижле и ткни пальцем в ту часть, где ты видишь компиляцию драйверов.
_>Ну так они просто уже скомпилированы и подключаются уже в бинарном виде.
Правильно. Потому никому не говори, что надо компилировать, да еще и линковать статически. Твои компиляции оказались экономически невыгодными. Потому от них и отказались.
I>>А то я вижу твоё выступление примерно так: "На С++ — у-у-у-у! D — а-а-а-а! Rust — o-o-o-o-o! C# — ???" I>>Чего ты конкретно сказать хотел ?
_>Я хотел сказать? ) Это ты начал какие-то разговоры про T4 и т.п.
Итак, ты отказался от своих слов "Проблема не в том как используют рефлексию в linq, а в том, что её вообще используют. ))) В то время как она не нужна и можно всё сделать во время компиляции."
Отказ принят
I>>То есть, ты сомневаешься что статистика на рсдн сделана через Linq ? Или намекаешь, что команда RSDN раскошелилась на миллион долларов что бы адское железо купить ? I>>Статистика как раз заработала очень быстро именно когда её на linq перевели.
_>Я думаю, что rsdn не является высоконагруженным сервисом. )))
В высоконагруженых используют аналогичные механизмы, только место EF будет другой ORM.
Здравствуйте, ·, Вы писали:
dot>В-третьих, без показаний профайлера разговоры о производительности — как минимум непрофессиональны.
Ох уж эти мантры про профайлер. В корне же неверно
Вот ты например разве не можешь исключительно смотря на код определить что он тормозной?
А код как пишешь, brute-force'ом и профайлером? Перебирая все комбинации, даже заведомо тормозные?
I>>В реальном приложении обращения к коллекции не все одинаковые, а это разные операции у которых, внезапно, разная частота использования. И вот этот расклад, внезапно, показывает профайлер !
EP>Однажды шеф дал мне кусок кода в ~250 строк из стороннего проекта, мол тормозит нужно оптимизировать.
EP>В том коде использовалась библиотека и среда которая у меня не была установлена+настроена. Используя только документацию по этой библиотеке и текстовый редактор (omg, без компилятора! ) я улучшил производительность в 10x на конкретных данных (а в общем случае и того больше) — при этом код собрался и заработал с первого раза, без ошибок и предупреждений.
EP>А ты говоришь profiler
Здравствуйте, ·, Вы писали:
·>В принципе согласен, что могут быть ситуации, когда тормоза начинают становиться значительными, но если это происходит относительно редко — это не повод отказываться от технологии. Скажем, compile-time тоже бесплатно не даётся. Сутки компиляции C++-шаблонов тоже может стать препятствием использования "zero-overhead".
Не, время компиляции шаблонов — это уже давно не проблема. В начале компиляторы немного подтянулись на эту тему, а затем появление ssd полностью решило эту проблему. Главный недостаток всех этих техник в другом — в сложности. В том смысле, что подобные инструменты требуют более высокой квалификации программистов, а это является недостатком в глазах бизнеса.
·>В общем, баланс. Инь-янь. И всё такое.
Здравствуйте, Evgeny.Panasyuk, Вы писали:
dot>>В-третьих, без показаний профайлера разговоры о производительности — как минимум непрофессиональны.
EP>Ох уж эти мантры про профайлер. В корне же неверно EP>Вот ты например разве не можешь исключительно смотря на код определить что он тормозной? EP>А код как пишешь, brute-force'ом и профайлером? Перебирая все комбинации, даже заведомо тормозные?
Нет, конечно. С опытом начинаешь сам распознавать типичные источники тормозов, априори, но даже это не во всех случаях помогает, всегда есть шанс обжечься неправильными предположениями: потратишь кучу времени на вылизывание байт, а скорости не добавит. В целом, производительность сколько-то большой системы без правильного инструментария вообще никак не оценивается, только гадание на кофейной гуще.
Да и вообще, я же отвечал в контексе высказываний alex_public, типа "раз рефлексия занимает время >0, то значит она источник тормозов". Нет, жаль, конечно, но не значит... ах как бы всё было просто тогда.
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Здравствуйте, ·, Вы писали:
·>Да и вообще, я же отвечал в контексе высказываний alex_public, типа "раз рефлексия занимает время >0, то значит она источник тормозов". Нет, жаль, конечно, но не значит... ах как бы всё было просто тогда.
Ну вообще то фраза "раз рефлексия занимает время >0, то значит она источник тормозов" является идеально верной априори. ))) Вот если бы там стояло "она главный источник тормозов", то уже можно было бы смело придираться. )))
Здравствуйте, Ikemefula, Вы писали:
_>>Ну так они просто уже скомпилированы и подключаются уже в бинарном виде. I>Правильно. Потому никому не говори, что надо компилировать, да еще и линковать статически. Твои компиляции оказались экономически невыгодными. Потому от них и отказались.
Что-то ты бредишь) Библиотеки в любом случае компилируются где-то, один раз. А линкуются динамически или статически — это уже по вкусу разработчиков. Мне больше нравится статическое решение, т.к. с ним меньше проблем при распространение.
_>>Я хотел сказать? ) Это ты начал какие-то разговоры про T4 и т.п. I>Итак, ты отказался от своих слов "Проблема не в том как используют рефлексию в linq, а в том, что её вообще используют. ))) В то время как она не нужна и можно всё сделать во время компиляции." I>Отказ принят
С чего бы мне от неё отказываться? ) Так а ты значит спорил с этой фразой значит? ) А где был хотя бы один аргумент с твоей стороны? )
_>>Я думаю, что rsdn не является высоконагруженным сервисом. ))) I>В высоконагруженых используют аналогичные механизмы, только место EF будет другой ORM.
Здравствуйте, alex_public, Вы писали:
_>Здравствуйте, ·, Вы писали:
_>·>Да и вообще, я же отвечал в контексе высказываний alex_public, типа "раз рефлексия занимает время >0, то значит она источник тормозов". Нет, жаль, конечно, но не значит... ах как бы всё было просто тогда.
_>Ну вообще то фраза "раз рефлексия занимает время >0, то значит она источник тормозов" является идеально верной априори. ))) Вот если бы там стояло "она главный источник тормозов", то уже можно было бы смело придираться. )))
Ну дык приведи главный источник тормозов Linq. Мне самому интересно.
И еще интересно как та в EF 7/ Тоже интересно. Ты же эксперт.
При первом выполнении запроса он проходит через внутренний компилятор плана для перевода концептуального запроса в команду хранилища (например, в инструкцию T-SQL при работе с SQL Server). Если кэширование плана запросов включено, то при следующей отправке запроса команда хранилища извлекается непосредственно из кэша плана запросов, минуя компилятор плана.
Кэш плана запросов совместно используется всеми экземплярами ObjectContext внутри одного домена приложения. Нет необходимости хранить экземпляр ObjectContext для получения преимуществ от кэширования плана запросов.
3.2.1. Некоторые замечания о кэшировании плана запросов
Кэш плана запросов совместно используется для всех типов запросов: Entity SQL, LINQ и объектов CompiledQuery.
По умолчанию кэширование плана запросов включено для запросов Entity SQL, выполняемых и через EntityCommand и через ObjectQuery. В EF 5.0 оно также по умолчанию включено для запросов LINQ. Кэширование планов запросов можно отключить, задав для свойства EnablePlanCaching (в EntityCommand или ObjectQuery) значение false.
Изменение значения параметра в параметризированных запросах не помешает извлечению нужных результатов из кэша. Однако изменение аспектов параметра (например, размер, точность и масштаб) приведет к извлечению другой записи из кэша.
При использовании Entity SQL строка запроса является частью ключа. Любое изменение запроса приведет к получение других записей из кэша, даже если запросы функционально эквивалентны. Сюда относится и изменение регистра, и пробелы.
При использовании LINQ из запроса формируется часть ключа. Изменение выражения LINQ приведет к созданию другого ключа.
Могут действовать и другие технические ограничения, дополнительные сведения см. в разделе Автоматические компилируемые запросы.
Там же
Наши тесты показали, что применение CompiledQuery может дать 7 % прироста по сравнению с запросами LINQ. Это означает, что при выполнении кода из стека Entity Framework будет затрачено на 7 % меньше времени. Это значит, что ваше приложение будет на 7 % быстрее. В целом затраты на написание и поддержку объектов CompiledQuery в EF 5.0 могут быть выше, чем получаемый от них прирост производительности. Впрочем, ваши результаты могут быть другими, поэтому используйте этот подход, если вашему проекту требуется дополнительная производительность.
Есть два момента, которые нужно учитывать при применении CompiledQuery — использование только статических экземпляров и проблемы с их компоновкой. Далее дается подробное описание этих двух моментов.
Здравствуйте, alex_public, Вы писали:
_>·>Да и вообще, я же отвечал в контексе высказываний alex_public, типа "раз рефлексия занимает время >0, то значит она источник тормозов". Нет, жаль, конечно, но не значит... ах как бы всё было просто тогда. _>Ну вообще то фраза "раз рефлексия занимает время >0, то значит она источник тормозов" является идеально верной априори. ))) Вот если бы там стояло "она главный источник тормозов", то уже можно было бы смело придираться. )))
Только в идеальном мире. Производительность не аддитивна. Допустим ты сравниваешь C++ compile time vs .net reflection. А что если, например, JIT в .net сгенерит более эффективный код, который в итоге сработает быстрее?
Или более очевидно — время запроса 100ms±1%, на рефлексию тратится <10us. Как ты докажешь, что рефлексия что-то замедляет, а не ускоряет?
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Здравствуйте, alex_public, Вы писали:
_>·>В принципе согласен, что могут быть ситуации, когда тормоза начинают становиться значительными, но если это происходит относительно редко — это не повод отказываться от технологии. Скажем, compile-time тоже бесплатно не даётся. Сутки компиляции C++-шаблонов тоже может стать препятствием использования "zero-overhead". _>Не, время компиляции шаблонов — это уже давно не проблема. В начале компиляторы немного подтянулись на эту тему, а затем появление ssd полностью решило эту проблему. Главный недостаток всех этих техник в другом — в сложности. В том смысле, что подобные инструменты требуют более высокой квалификации программистов, а это является недостатком в глазах бизнеса.
Правильно, но тут не только квалификация. Даже 10 секунд на компиляцию может стать препятствием. Если код на .net показывает результат работы тестов через 1с после правки, а C++ через 10с, то уже стоит задуматься — а стоит ли того эта 1мкс задержка при выполнении?
9 секунд работы программиста может оказаться значительно дороже 1мкс работы железки.
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Здравствуйте, alex_public, Вы писали:
_>Что-то ты бредишь) Библиотеки в любом случае компилируются где-то, один раз. А линкуются динамически или статически — это уже по вкусу разработчиков. Мне больше нравится статическое решение, т.к. с ним меньше проблем при распространение.
Вкус разработчиков никого не интересует. Деплойментом, майнтенансом и траблшутингом сервера занимаются не они.
Со статической линковкой нужно перекомпилировать каждый раз, вместо простого обновления драйверов.
I>>Итак, ты отказался от своих слов "Проблема не в том как используют рефлексию в linq, а в том, что её вообще используют. ))) В то время как она не нужна и можно всё сделать во время компиляции." I>>Отказ принят
_>С чего бы мне от неё отказываться? ) Так а ты значит спорил с этой фразой значит? ) А где был хотя бы один аргумент с твоей стороны? )
Я выяснил, что тебе нечего было сказать. Соотсвенно мне нечего тебе пояснить
I>>В высоконагруженых используют аналогичные механизмы, только место EF будет другой ORM. _>Угу, без linq. )))
Высоконагруженые приложения это не про sql вместо linq, а про масштабирование. То есть, в высоконагруженых приложениях узкое совсем не linq, а архитектура — всевозможные фермы, кластерные решения, балансировщики нагрузки и тд. Сюда же кеш страниц, кеш данных и тд. Основные проблемы связаны с инвалидацией кеша, который обычно в каком нибудь out-process memcached.
Здравствуйте, Evgeny.Panasyuk, Вы писали:
EP>Ох уж эти мантры про профайлер. В корне же неверно
И ежу понятно, что речь про замеры.
EP>Вот ты например разве не можешь исключительно смотря на код определить что он тормозной?
Если ты никогда не делал замеры то шансов немного.
EP>Конкретный пример: EP>
EP>>Однажды шеф дал мне кусок кода в ~250 строк из стороннего проекта, мол тормозит нужно оптимизировать.
EP>>В том коде использовалась библиотека и среда которая у меня не была установлена+настроена. Используя только документацию по этой библиотеке и текстовый редактор (omg, без компилятора! ) я улучшил производительность в 10x на конкретных данных (а в общем случае и того больше) — при этом код собрался и заработал с первого раза, без ошибок и предупреждений.
Профайлер это инструмент, который делает за тебя замеры. 10х это значит результаты замеров до поделить на результаты замеров после.
_>Нет, в результате работы подобного инструмента должны генерироваться не некие готовые строки (это же физически невозможно, т.к. в них в них обычно входят пользовательские данные), а код склейки нескольких строк и параметров из остальной части программы. Естественно такое тоже реализуемо в любом языке с какой-то разновидностью метапрограммирования (сюда можно включить и препроцессоры типа t4), в теории. А вот на практике я про такое слышал в C++, в Rust'е, в D. А вот в C# (t4?) что-то не слышал. )))
Я тебе приводил давненько примеры на предварительной компиляцией запроса. Так, что если нужна скорость такие запрсы компилирутся автоматически. Проблемы возникают с динамическими запросами в зависимости от условий.
В этом случае нужно склеивать строки в рантайме. А таких вещей вагон и маленькая тележка. Большинство.
_>>>Всё правильно. Берём оверхед от рефлексии и всего остального и сравниваем со временем выполнения запроса. Если там будут не десятки процентов, то естественно можно наплевать на это всё.
Я тебе умную вещь скажу. Только ты не обижайся. Во главе угла удобство кодирования и скорость разработки. Вот ты не знаешь, что такое 1С, а это самая популярная программа для учета в России. И 1С ники самые востребованные программисты. При этом средний уровень не очень высок. Я никак не могу продвинуть использование классов .Net в 1С. Но при этом нужно много кодировать и 1С предоставляет возможность быстро решать задачи. Так, что C# это вообще ракета, но и он сложен. При этом 1С не только в ларьках, но и средних и даже крупных предприятиях.
По мне так, на шарпе удобнее. Это как TS vs JS.
и солнце б утром не вставало, когда бы не было меня
Здравствуйте, AndrewVK, Вы писали:
I>>В высоконагруженых используют аналогичные механизмы, только место EF будет другой ORM.
AVK>На rsdn используется не EF, а linq2db. Быстрее только руками.