Здравствуйте, __kot2, Вы писали:
__>нужно не пробовать подход с маленькими ф-иями, а подход с написанием юнит-тестов. вы быстро выясните, что при привычном подходе вам тестов придется писать еще и больше кода и, постепенно поймете, как разбить все на маленькие назависимые, скомпонованные между собой модули, чтобы изменения в одном не тянули изменений в другом.
А вот скажи мне как писать тесты до кода если задача ставится так:
Сделай хрень, которая должна делать примерно то-то. Возможны небольшие отклонения от идеального решения, ибо идеальное решение будет работать дольше жизни вселенной.
При этом нужно уложится в 50 миллисекунд. А лучше в 10.
Имей в виду что при решении таких задач весь код несколько раз переписывается.
__>но скорее всего вы плюнете на эту задумку и оставите только функциональные тесты, время выполнения которых постепенно докатится до 4 часов на коммит и вы, наконец, поймете, в чем разница между юнит тестами и функциональными.
Запускать все тесты на каждый коммит весьма странная затея.
Полностью тестировать нужно только перед отправкой кода в главную ветку. А рабочие ветки могут даже не компилироваться. И ничего плохого в этом нет.
... << RSDN@Home 1.2.0 alpha 5 rev. 62>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Здравствуйте, dosik, Вы писали:
P>>А еще не нужно давать объектам, используемым в программе, длинные имена. Накладные расходы на печатание увеличиваются. При компиляции память занимают.
D>Вот только Вас с Вашими шутками тут и ждали. Дождались!!! Все, можно закрывать тему!
Дак ведь тоже экономия ресурсов, только не при выполнении, а при сборке.
У всего этого ноги растут в 70-е — 80-е годы, эпоху расцвета ЕС ЭВМ. Насколько я помню, именно тогда не рекомендовали делать подпрограммы из-за дороговизны их вызова. Я буквально слегка эту эпоху зацепил, углубиться не успел. У ЕС ЭВМ подготовка к вызову была, насколько я знаю, дорогой процедурой. Там не было аппаратного стека, подобного PC-шному. Поэтому нужно быдо выделить память, сохранить туда все, что нужно, позвать подпрограмму, восстановить все после окончания ее работы.
Мне приходилось видеть числодробилки, написанные в те годы на Фортране 4. Некоторые из ник представляли из себя ровно то, о чем Вы пишете: 5000 строк находятся в главной программе. Работало быстро, но прочитать это было невозможно. В том числе, кстати, из-за имен. Тогдашние компиляторы Фортрана распознавали в имент только 6 символов, игнорируя остальные. Например, MYNAME1 и MYNAME2 компилятором не различались. Поэтому никто не заморачивался с ними. Даже наоборот: используя короткое имя, снижалась вероятность ошибки. Такие дела.
Здравствуйте, IT, Вы писали: IT>Ты очень невнимательный. Я тебе уже говорил, что Expressions — это часть .NET Framework. Выкачать его исходники ты сейчас сможешь и даже собрать. Но вот переписать несколько классов тебе вряд ли кто-нибудь позволит из Microsoft. По крайней мере до тех пор пока ты не научишься писать компилируемый код.
то есть стандартный класс нам диктует как писать код?
если ваша абстракция не полностью соотв-ет стандартному классу, то все, ничего нельзя поделать?
IT>Всё так. Только при чём тут 'микро функции рулят'?
для того, чтобы понять что делает блок кода, нужно изучить его построчно.
чтобы не изучать дважды можно выделить его в блок и написать короткий коммент сверху, что он и как реально делает
ну и совсем чтобы довести идею стоит коммент превратить в имя ф-ии и вынести этот блок в отдельую ф-ию
Здравствуйте, WolfHound, Вы писали: __>>нужно не пробовать подход с маленькими ф-иями, а подход с написанием юнит-тестов. вы быстро выясните, что при привычном подходе вам тестов придется писать еще и больше кода и, постепенно поймете, как разбить все на маленькие назависимые, скомпонованные между собой модули, чтобы изменения в одном не тянули изменений в другом. WH>А вот скажи мне как писать тесты до кода если задача ставится так: WH>Сделай хрень, которая должна делать примерно то-то. Возможны небольшие отклонения от идеального решения, ибо идеальное решение будет работать дольше жизни вселенной. WH>При этом нужно уложится в 50 миллисекунд. А лучше в 10.
вот меня кстати удивляет когда люди пишут такие задачи без юнит тестов, по крайней мере на сам алгоритм.
потом чего-нить поломается, они "ща" и как слесарь с сигареткой в зубах, лезут в щиток, там что-то подогнут и "ну все, заводи заново"
разумеется все типичные и переломные точки обработки должны собираться в коллекцию и тестироваться.
WH>Имей в виду что при решении таких задач весь код несколько раз переписывается.
вы мне просто мою работу описываете. если кто-то придет и скажет "я пеерписал весь код, теперь он работает правильно и быстро", я скажу — "докажи!". учитывайте, что даже x264 кодек знаменит тем, что дает битые кадры периодически, хотя вроде бы тысячи людей постоянно гоняют на нем какие-то свои тесты.
вы считаете, что если "на большом тесте все проходит", то и ошибок более низкого уровня нет? да полно багов было обнаружено в результате юнит-тестов даже в современных процессорах, я как-то отчет видел от компании, которая это делала у нас на этаже. им, собн-о, за эти тесты и платили.
даже в процессорах находят баги после мега-тестирования. то с делением, то с кэшем, то с транзакционной памятью. и это только самые громкие случае, на самом деле даже в вашем проце с десяток багов-то наберется, просто они проявляются не часто и не так явно. подумаешь, там, программка повиснет. а вы мне рассказываете про некое Васино поделие, которое он только что переписал и у себя на компе на своем наборе тестов проверил и терерь думает, что там все правильно. да неправильно оно. вопрос только где и как мы это будем локализовать.
__>>но скорее всего вы плюнете на эту задумку и оставите только функциональные тесты, время выполнения которых постепенно докатится до 4 часов на коммит и вы, наконец, поймете, в чем разница между юнит тестами и функциональными. WH>Запускать все тесты на каждый коммит весьма странная затея. WH>Полностью тестировать нужно только перед отправкой кода в главную ветку. А рабочие ветки могут даже не компилироваться. И ничего плохого в этом нет.
и отправда в главную ветку это целое эпохальное событие с неожиданной развязкой? батюшку приглашаете для освящения сервера, дабы повысить шансы, что ничего не сломается? никаких других вариантов пока не придумали?
КТ>>Соответсвенно, вопрос только в том, где такое критично, а где — нет. Числодробилки, рендеринги и прочая — это опять же сколько, 0.0001% задач? И то, там опять же критичны в первую очередь алгоритмы, а потом — выжимание скорости из железа.
I>Пудозреваю, в твоих проектах это не надо делать.
Тут у всех подряд на форуме это не надо делать. Тут считанные единицы работают хоть с какой-либо нагрузкой или числодробилками.
I>Например, когда вызов функции у тебя асинхронный, это само по себе дает счет на милисекунды. Что характерно, компилятор тут вообще не помощник. Если руками заинлайнить, то профит вообще сказочный.
Что заинлайнить? Куда заинлайнить?
I>Перформанс это не "надо-не надо" а "какие возможности даёт". Алгоритмы — это и ежу понятно. Константы во всяких O(log(N)) никто не отменял, O(K*N^2) может работать быстрее, нежели O(M*log(N)). Или так — сортировка пузырьком, когда данные отсортированы, работает быстрее квиксорта и мержсорта.
I>То есть, вне зависимости от хорошести алгоритма, потери на вызовах могут быть и 1000% и больше.
Сферовакуумные потери сферовакуумных вызовов. Да еще «вне зависимости от алгоритма». Ага, как же. Эти сказки рассказывай бабушкам на крылечке у дома.
Даже в той же Java стоимость вызова выглядит примерно так:
— худший вариант: 0.135 ns/op
— лучший вариант: 0.004 ns/op
Не, технически ты прав: тут ужасный performance penalty, потеря на вызове — больше 1000%!!! Только что-то мне внезапно подсказывает:
— чтобы заметить эту разницу, вызовов должны быть миллионы
— замена алгоритма O(n^2) на O(log(n)) даст прирост производительности и быстродействия гораздо более ощутимый, чем погоня за инлайнингом функций
MC>2) С одной стороны код становился понятнее; с другой стороны, при чтении кода приходилось прыгать по куче функций, чтобы понять, что происходит. Так же часто приходилось пользоваться решарперовским Find Usages, чтобы посмотреть откуда вызывается эта микро-функция, только чтобы увидеть, что вызывается она из одного места. При отладке тоже не нравилось прыгать по куче микро-функций. Не конец света, конечно, но не айс.
Имхо, микро-мини-функции хороши в пределах одного модуля, экспортирующего свой функционал в виде одного-двух API-вызовов.
Тогда получается вполне хорошо:
— достаточно крупный кусок самодостаточной логики помешается в модуль
— внутри себя разбивается на небольшие функции, которые отвечают за какие-то внутренние логические куски
— извне это выглядит, как черная коробка с внятным API
Понятно, что это — утопия, но, пытаясь к такой утопии прийти, можно получить нормальный удобоваримый код.
Здравствуйте, __kot2, Вы писали:
WH>>Сделай хрень, которая должна делать примерно то-то. Возможны небольшие отклонения от идеального решения, ибо идеальное решение будет работать дольше жизни вселенной. WH>>При этом нужно уложится в 50 миллисекунд. А лучше в 10. __>вот меня кстати удивляет когда люди пишут такие задачи без юнит тестов, по крайней мере на сам алгоритм.
Ну так ты расскажи как?
Точное решение не подходит, ибо неприемлемо долго.
Иногда даже нельзя чётко сформулировать что значит точное решение.
Те до того, как задача решена невозможно даже сказать, что должно быть на выходе.
Те ты даже функциональный тест на всю задачу написать не сможешь.
А юнит тесты тоже писать невозможно, ибо детали реализации алгоритма могут изменятся до неузнаваемости по 10 раз в месяц.
Обычное дело: сегодня написал функцию, а завтра удалил. Ну и зачем писать тест, на код, который прожил сутки?
WH>>Имей в виду что при решении таких задач весь код несколько раз переписывается. __>вы мне просто мою работу описываете.
Больше похоже на то что я разговариваю с человеком, который всю жизнь переливал данные из БД в ГУИ и обратно, но очень хочет выглядеть крутым.
__>если кто-то придет и скажет "я пеерписал весь код, теперь он работает правильно и быстро", я скажу — "докажи!".
Доказать? Тестами?
Тесты ловят только регрессии.
Причем регрессии не всегда являются ошибками.
WH>>Запускать все тесты на каждый коммит весьма странная затея. WH>>Полностью тестировать нужно только перед отправкой кода в главную ветку. А рабочие ветки могут даже не компилироваться. И ничего плохого в этом нет. __>и отправда в главную ветку это целое эпохальное событие с неожиданной развязкой? батюшку приглашаете для освящения сервера, дабы повысить шансы, что ничего не сломается? никаких других вариантов пока не придумали?
Да ты ещё и читать не умеешь? Как же ты программы то пишешь?
Может отсюда и пошла страсть к мелким функциям.
... << RSDN@Home 1.2.0 alpha 5 rev. 62>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Здравствуйте, WolfHound, Вы писали: WH>А юнит тесты тоже писать невозможно, ибо детали реализации алгоритма могут изменятся до неузнаваемости по 10 раз в месяц.
то есть вы пишите код и обьявляете его правильным? "силой, данной мне универом, обьявляю этот код корректным?"
или проводите какое-то тестирование? какое? ручное? а когда что-то меняете? снова проводите ручное тестирование? своего времени не жалко?
WH>Обычное дело: сегодня написал функцию, а завтра удалил. Ну и зачем писать тест, на код, который прожил сутки?
да я часто бывает неделю пишу программку и выкидываю ее целиком
что я вижу, это когда люди пробуют какой-то подход, он им кажется, что он не работает. и они пробуют другой. а реально у них просто баг был в том коде и он не работал из-за этого. вот не жалко людям своего времени совсем.
WH>>>Имей в виду что при решении таких задач весь код несколько раз переписывается. __>>вы мне просто мою работу описываете. WH>Больше похоже на то что я разговариваю с человеком, который всю жизнь переливал данные из БД в ГУИ и обратно, но очень хочет выглядеть крутым.
я очень удивлен, что очевидные вещи, которые я тут говорю, встречаются с огнем и вилами. если вы давно выпали из современной разработки, предлагаю начать потихоньку впадать обратно и начать хотя бы с чтения writing secure code — кстати, уже достаточно старого баяна.
WH>Доказать? Тестами? WH>Тесты ловят только регрессии. WH>Причем регрессии не всегда являются ошибками.
думаете, в коде IT нет багов? да миллион. просто они на его тестах или не проявляются или он их пропускает. и как, интересно, он думает поступать в случае, когда проектом станут пользоваться толпы людей и повалятся тысячи багрепортов? начать веерные правки?
WH>Да ты ещё и читать не умеешь? Как же ты программы то пишешь?
ладно, похоже, тема переходит в бисерометание, по крайней мере с моей стороны, поэтому закругляюсь, чтобы больше не раздражжать людей. я свою мысль по-моему достаточно четко выразил
Здравствуйте, __kot2, Вы писали:
__>любой человек, который до сих пор пишет ф-ии в столбик строк по 30, вставляя туда комменты просто неквалифицирован и его нельзя допускать до написания реального кода
По мне так читать логику хоть на 300 строк с комментариями удобнее, чем прыгать по методам и смотреть, что они там реализуют.
Все должно быть подчинено читабельности и минимизации кода за счет повторного использования кода в методах.
Например в VS удобно просмотреть код метода по месту вызова, а вот например в 1С такой возможности нет.
и солнце б утром не вставало, когда бы не было меня
Здравствуйте, __kot2, Вы писали:
__>то есть стандартный класс нам диктует как писать код? __>если ваша абстракция не полностью соотв-ет стандартному классу, то все, ничего нельзя поделать?
При чём тут моя абстракция?
Есть пример кода, который использует стандартный класс, который нельзя расширять. Нужно этот код переписать в 10 строк. Продемонстрируй мастер класс.
Если нам не помогут, то мы тоже никого не пощадим.
Здравствуйте, __kot2, Вы писали:
__>маленькие ф-ии это еще полдела. они должны быть названы так, чтобы по названию было понятно, что она делает, не заглядывая внутрь. и сами классы тоже должны быть маленькими и называться не datahelper, а так, чтобы вы могли понять что делает этот класс, не заглядывая в него. так, например, ф-ия работы с временной зоной не должна находиться внутри utils.cs и являться частью класса datetimehelper, она должна называться timezone и находиться в модуле timezone или хотя бы datetime
Понятное именование и хорошее структурирование это как бы само собой разумеещееся.. Только я не понял про функцию работы с временной зоной, которая должна находиться в модуле timezone. Что тут подразумевается под модулем? И ещё, что плохого если функция будет находиться, например, в классе DateTimeExtensions (предоставляющем extension methods для DateTime)?
__>и вам не придется никуда прыгать по коду, так как класс timezone описывает временную зону и странно ожидать там что-то другое
А если мне надо посмотреть как оно там работает? Если ко мне подходит бизнес-аналитик и просит посмотреть как работает расчет Number of Shares in Issuance, потому что возможно где-то в алгоритме у нас ошибка? Если у меня есть метод CalculateNSI(Issuer issuer) на 1 экран (как сейчас реально есть), я просто открою его и всё будет на ладони. Если же я его открою, а там вызовы других функций, я начну в них заходить, смотреть что там делается, возвращаться, заходить в следующую функцию и т.д.
MC>>В результате я как-то забросил подход с микро-функциями и все эти субъективные лимиты (в 5-10 строк, полэкрана, 1 экран, 2 экрана, 30 строк и т.д.) и тупо продолжил писать по ситуации: вижу что лучше сделать extract method — делаю, если функция на 1-2 экрана отлично читается линейно или её сложно уменьшить — оставляю как есть. __>а тесты?
Тесты как писались, так и пишутся
__>нужно не пробовать подход с маленькими ф-иями, а подход с написанием юнит-тестов. вы быстро выясните, что при привычном подходе вам тестов придется писать еще и больше кода
Exception : The timeout period elapsed prior to completion of the sentence parsing.
__>но скорее всего вы плюнете на эту задумку и оставите только функциональные тесты, время выполнения которых постепенно докатится до 4 часов на коммит
У меня несколько сот написанных мной тестов (вперемешку, юнит- и функциональных) выполняются где-то минуту. Что я делаю не так?
В Linq2db (это тот самый проект с "непродуманной архитектурой", из которого приводили метод на 250-300 строк) 40000 тестов выполняются 15 минут. Как так?
__>и вы, наконец, поймете, в чем разница между юнит тестами и функциональными.
А в чём разница? Может я правда её до сих пор не знаю, судя по тому что вы (я перейду обратно на вы, кажется вам так комфортнее) написали? Или вы просто думаете, что вокруг вас только вчерашние студенты, не знающие разницы (ну или "старпёры застрявшие в 90-х")?
Здравствуйте, IT, Вы писали: IT>При чём тут моя абстракция? IT>Есть пример кода, который использует стандартный класс, который нельзя расширять. Нужно этот код переписать в 10 строк. Продемонстрируй мастер класс.
откуда такое странное нельзя? кто запрещает-то? это незаконно, чтоли?
я сначала пишу код так, как если бы я выразил его словами
то есть вообще-то это обход дерева — tree_traversal
или в раскрытом виде — лямбда на ноде и рекурсивно вызов для дочерних нодов.
это и называется — ф-ия делает одну вещь. она обходит дерево. все остальное не относится к обходу дерева и не должно быть в этой ф-ии, чего бы мы с деревом не делали. и она не должна называться visit, transform или там do, чтобы не занимапться гаданиями на тему что же там реально внутри проихсодит
потом уже когда становятся понятны используемые абстракции, можно их описать, часто даже переиспользуя стандартные. в C# есть стандартные достаточно параметризуемые алгоритмы работы с деревьями? если да, то зачем нам вообще писать свой traversal? нельзя ли написать что-то в духе Tree<>::in_order_traversal(expression, f) ? вам что, правда нужно заглянуть внутрь этого метода, чтобы узнать как он реализован? вы не знаете, что такое in order tree traversal?
Здравствуйте, dosik, Вы писали:
D>В своей книге Р. Мартин утверждает, что функции необходимо предъявлять всего два требования: D>1. они должны быть компактными D>2. они должны быть еще более компактными D>Т.е. функция должна выполнять лишь одну операцию. Функции, выполняющие несколько операций необходимо дробить на несколько. D>Тогда вопрос: А как же накладные расходы на вызов функции? Ведь вместо того, чтобы продолжить вычисления, теперь нам надо заполнить стек и передать управление по адресу, а по возвращению очистить стек. Т.е. улучшая читабельность кода мы уменьшаем производительность системы. Да и как то меня учили, что в функцию необходимо выносить лишь тот код, который может быть вызван из нескольких участков программы. И какой тогда смысл выносить в отдельную функцию код, который будет вызываться только в одном месте?
Приходилось как-то ковырять исходники, в которых декомпозиция и вынесение повторяющихся кусков кода в отдельные функции было доведено до абсурда.
Почти любой фрагмент кода между if{ и } оформлялся в виде отдельной самостоятельной функции.
А в этой самостоятельной функции использовался тот же прием и так далее по рекурсии.
Глубина стека вызовов до пятидесяти доходила, а бизнес логика равномерно размазана по этажам стека вызовов.
Чтение кода превращалось в бесконечное разматывание соплей из вызовов функций, после пятого, шестого перехода мозг уже не помнит зачем он сюда пришел.
Где-то надо уметь остановиться и не доводить любую идею до абсурда.
--------------------------------------------------------------
Правильно заданный вопрос содержит в себе половину ответа
Здравствуйте, __kot2, Вы писали:
__>то есть вы пишите код и обьявляете его правильным? "силой, данной мне универом, обьявляю этот код корректным?"
А кто поступает иначе?
Есть конечно люди, которые доказывают программы. Но их мизерное количество.
__>или проводите какое-то тестирование? какое? ручное? а когда что-то меняете? снова проводите ручное тестирование? своего времени не жалко?
А на этот случай есть регрессионные тесты.
Написал код.
Сделал несколько наборов тестовых данных.
Натравил код на каждый набор.
Записал результат в фиал.
После чего просто прогоняю тесты и сравниваю с эталоном.
Если нашёлся баг делаю новый набор данных на котором воспроизводится баг.
Чиню баг.
Генерирую эталон.
После чего стало на один тест больше.
__>что я вижу, это когда люди пробуют какой-то подход, он им кажется, что он не работает. и они пробуют другой. а реально у них просто баг был в том коде и он не работал из-за этого. вот не жалко людям своего времени совсем.
Почему ты решил, что это ко мне относится?
Я выкидываю код только после того как становится ясно почему он фундаментально ущербен.
При этом получаю ценную информацию для следующей итерации.
__>я очень удивлен, что очевидные вещи, которые я тут говорю, встречаются с огнем и вилами.
Просты ты чушь порешь. А ей больно.
WH>>Доказать? Тестами? WH>>Тесты ловят только регрессии. WH>>Причем регрессии не всегда являются ошибками. __>думаете, в коде IT нет багов?
Ты от вопроса не уходи.
Что ты собрался тестами доказать?
Доказывают вот так: http://thedeemon.livejournal.com/107067.html
А тестами ловят регрессии и только регрессии.
Ибо сущность любого теста зафиксировать результат работы кода на конкретном наборе данных.
Ничего больше тесты не могут.
WH>>Да ты ещё и читать не умеешь? Как же ты программы то пишешь? __>ладно, похоже, тема переходит в бисерометание, по крайней мере с моей стороны, поэтому закругляюсь, чтобы больше не раздражжать людей. я свою мысль по-моему достаточно четко выразил
Ты достаточно чётко слил.
... << RSDN@Home 1.2.0 alpha 5 rev. 62>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Здравствуйте, MozgC, Вы писали: MC>Понятное именование и хорошее структурирование это как бы само собой разумеещееся.. Только я не понял про функцию работы с временной зоной, которая должна находиться в модуле timezone. Что тут подразумевается под модулем? И ещё, что плохого если функция будет находиться, например, в классе DateTimeExtensions (предоставляющем extension methods для DateTime)?
вот вы идете мимо забора. на нем написано "городской военный комиссариат ленинского района города Москвы". понятно, что внутри? понятно
а теперь вы идете мимо другого забора, там написано "всякие дополнительные военные штуки". что это такое? непонятно. что такое "дополнительные свойства datetime" ? я без понятия. расчет релятивистких эффектов? марсианские сутки? сериализация? форматирование? поддержка времени хищника? название ни о чем не говорит.
MC>А если мне надо посмотреть как оно там работает? Если ко мне подходит бизнес-аналитик и просит посмотреть как работает расчет Number of Shares in Issuance, потому что возможно где-то в алгоритме у нас ошибка? Если у меня есть метод CalculateNSI(Issuer issuer) на 1 экран (как сейчас реально есть), я просто открою его и всё будет на ладони. Если же я его открою, а там вызовы других функций, я начну в них заходить, смотреть что там делается, возвращаться, заходить в следующую функцию и т.д.
а алгоритм побуквенно переписан из древнего писания или имеет какие-то вполне разумные части, типа, расчета credit score или поправка на семейное положение? этот алгоритм можно записать текстом так, чтобы его прочитал и с первого раза понял любой человек? или там просто в столбик строчки типа
exptr2 += dev_thrillx(20, rack, grad_fix) * e + 8 * cutted_value/2
и для понимания значения их, нужно сидеть и весь день тупить в экран, ходить, выяснять, что там за phred и почему там стоит 8 ?
Здравствуйте, __kot2, Вы писали:
IT>>Есть пример кода, который использует стандартный класс, который нельзя расширять. Нужно этот код переписать в 10 строк. Продемонстрируй мастер класс. __>откуда такое странное нельзя? кто запрещает-то? это незаконно, чтоли? __>я сначала пишу код так, как если бы я выразил его словами
Объекты этих типов генерирует компилятор C#. Для того чтобы их изменить нужно:
1)Написать компилятор C#
2)Уговорить всех пользователей Linq2DB перейти на этот компилятор.
Если первое ещё можно сделать. То второе почти не реально.
ЗЫ Linq2DB лучшая в мире реализация linq для реляционных баз данных.
... << RSDN@Home 1.2.0 alpha 5 rev. 62>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Здравствуйте, К Тёте, Вы писали:
I>>Пудозреваю, в твоих проектах это не надо делать.
КТ>Тут у всех подряд на форуме это не надо делать. Тут считанные единицы работают хоть с какой-либо нагрузкой или числодробилками.
Тут минимум в трех форумах оптимизации вызывают очень бурное обсуждение. В микроконтролерах-железе это актуально по сей день. Системное программирование — так же. Геймдев — снова числодробилки. hft, hpc, САПР — снова надо. Визуализации, аналитика всех сортов — обратно надо. Обработка изображений, звука, сигналов — адски актуально. Чуть не все хранение-обработка данных так или иначе связано с перформансом.
А вот где неактуально — обычный мейнстрим да магазины на трёх с половиной юзеров. Вот здесь как правило задачи очень мирные, но это в основном потому, что уже давно известно, что убер-алгоритмы недоступны а выжимать соки смысла нет.
I>>Например, когда вызов функции у тебя асинхронный, это само по себе дает счет на милисекунды. Что характерно, компилятор тут вообще не помощник. Если руками заинлайнить, то профит вообще сказочный.
КТ>Что заинлайнить? Куда заинлайнить?
Вызов функции. В вызывающую функцию.
I>>То есть, вне зависимости от хорошести алгоритма, потери на вызовах могут быть и 1000% и больше.
КТ>Сферовакуумные потери сферовакуумных вызовов. Да еще «вне зависимости от алгоритма». Ага, как же. Эти сказки рассказывай бабушкам на крылечке у дома.
Если у тебя обращение к элементу массива требует K приседаний, то и медленная версия, и супероптимизированая версия алгоритма, могут быть ускорены в K раз, при условии, что они зависят от длины массива N.
Собтсвенно именно отсюда и начинается разговор о производительность
1. низкоуровневые оптимизации это краткосрочная перспектива, быстрый эффект
2. улучшение алгоритмов это долгосрочная перспектива.
3. Алгоритмы меняются не просто так, а именно с учетом того самого K-на-каждую итерацию. То есть, вместо "руками пофиксим тысячу мест и получим K/10 и огребем проблемы с релизом и майнтенансом" у тебя будет алгоритм, который будет очень чувствительным именно к K и потребует низкоуровневые приседания ровно в одном месте.
4. Дело десятое, меняешь ли ты N^2 на log(N) или наоборот, главное что бы на твоём промежутке был профит. То есть, и замена быстрой на пузырек, и обратная замена могут быть, а могут и не быть оптимизациям.
I>А вот где неактуально — обычный мейнстрим да магазины на трёх с половиной юзеров. Вот здесь как правило задачи очень мирные, но это в основном потому, что уже давно известно, что убер-алгоритмы недоступны а выжимать соки смысла нет.
Это неактуально и для магазинов с 10 000 пользователями и со 100 000 пользователей.
I>>>Например, когда вызов функции у тебя асинхронный, это само по себе дает счет на милисекунды. Что характерно, компилятор тут вообще не помощник. Если руками заинлайнить, то профит вообще сказочный. КТ>>Что заинлайнить? Куда заинлайнить?
I>Вызов функции. В вызывающую функцию.
Зачем? Что это даст при асинхронном вызове? Я тебе привел пример: вызов функции — это наносекунды. У тебя латентность сети, доступ к диску и обращение к базе съедят любую придуманную твоей буйной фантазией оптимизацию от инлайнинга.
I>>>То есть, вне зависимости от хорошести алгоритма, потери на вызовах могут быть и 1000% и больше.
КТ>>Сферовакуумные потери сферовакуумных вызовов. Да еще «вне зависимости от алгоритма». Ага, как же. Эти сказки рассказывай бабушкам на крылечке у дома.
I> Если у тебя обращение к элементу массива требует K приседаний, то и медленная версия, и супероптимизированая версия алгоритма, могут быть ускорены в K раз, при условии, что они зависят от длины массива N.
Именно, фейспалм. От твоих текстов. Вызов функции в худшем варианте — 0.1 ns. Тебе расшифровать, что такое ns или сам догадаешься? Сколько должно быть вызвов этой функции, чтобы ее оптимизация до 0.04 ns дало хоть какой-то видимый прирост производительности по сравнению с заменой неоптимизированного алгоритма на оптимизированный?
I>Собтсвенно именно отсюда и начинается разговор о производительность
Нет. Разговор о производительности всегда должен начинаться с алгоритмов.
WH>Ибо сущность любого теста зафиксировать результат работы кода на конкретном наборе данных. WH>Ничего больше тесты не могут.
Если нет верификатора, то (quickchek и иже с ним):
— тесты должны описывать спецификацию, а не работу кода
— тесты должны автогенерировать большой набор данных согласно спецификации
— тесты должны проверять, соответсвует ли работа кода спецификации
В итоге такие тесты выявят проблемы как в коде, так и в спецификации. Понятное дело, что даже такое не гарантирует 100% доказательство, но это лучше, чем вручную написанные тесты на ограниченном наборе данных, описывающие работу кода.
Здравствуйте, К Тёте, Вы писали:
I>>Вызов функции. В вызывающую функцию.
КТ>Зачем? Что это даст при асинхронном вызове?
Милисекунды экономии. На тысяче вызовов сэкономишь секунду времени отклика приложения.
>Я тебе привел пример: вызов функции — это наносекунды. У тебя латентность сети, доступ к диску и обращение к базе съедят любую придуманную твоей буйной фантазией оптимизацию от инлайнинга.
1 Доли секунд можно не распылять, а потратить на более серьезное вычисление оптимального плана чтения с файловой системы, что в сумме сэкономит годы вагон трафика-времени-денег. Такими вещами занимется например операционная система, движок бд, серьезные серверные приложения и тд.
2 речь то про самые разные применения. Ты вот уверен, что в любом ЯП и любой VM вызов будет наносекундами меряться ?
I>> Если у тебя обращение к элементу массива требует K приседаний, то и медленная версия, и супероптимизированая версия алгоритма, могут быть ускорены в K раз, при условии, что они зависят от длины массива N.
КТ>Именно, фейспалм. От твоих текстов. Вызов функции в худшем варианте — 0.1 ns. >Тебе расшифровать, что такое ns или сам догадаешься? Сколько должно быть вызвов этой функции, чтобы ее оптимизация до 0.04 ns дало хоть какой-то видимый прирост производительности по сравнению с заменой неоптимизированного алгоритма на оптимизированный?
Ты свою статью то открой. Как только до полиморфизма доходит, так время сразу 4.278ns
Это как раз те самые 1000% разницы. Это может выстрелить и выстреливает в задачах из списка выше. Именно потому С++ девелоперы и до сих пор востребованы на рынке. А кроме них подобными оптимизациями занимаются и в других языках.
I>>Собтсвенно именно отсюда и начинается разговор о производительность
КТ>Нет. Разговор о производительности всегда должен начинаться с алгоритмов.
О производительности — требований, далее — с замеров, показаний профайлера и достоверных сведений о проблемах. Если этого нет, то нет и оснований заводить разговор об алгоритмах.