Функции должны быть компактными
От: dosik Россия www.dosik.ru
Дата: 25.04.16 15:41
Оценка: +1 -2
В своей книге Р. Мартин утверждает, что функции необходимо предъявлять всего два требования:
1. они должны быть компактными
2. они должны быть еще более компактными
Т.е. функция должна выполнять лишь одну операцию. Функции, выполняющие несколько операций необходимо дробить на несколько.
Тогда вопрос: А как же накладные расходы на вызов функции? Ведь вместо того, чтобы продолжить вычисления, теперь нам надо заполнить стек и передать управление по адресу, а по возвращению очистить стек. Т.е. улучшая читабельность кода мы уменьшаем производительность системы. Да и как то меня учили, что в функцию необходимо выносить лишь тот код, который может быть вызван из нескольких участков программы. И какой тогда смысл выносить в отдельную функцию код, который будет вызываться только в одном месте?
Re: Функции должны быть компактными
От: alpha21264 СССР  
Дата: 25.04.16 16:06
Оценка: +1
Здравствуйте, dosik, Вы писали:

D>Т.е. функция должна выполнять лишь одну операцию. Функции, выполняющие несколько операций необходимо дробить на несколько.

D>Тогда вопрос: А как же накладные расходы на вызов функции?

Это дело компилятора. Сейчас компилятор много чего без тебя инлайнит.
Да и вообще — кому сейчас нужно ловить настолько мелких блох?
Чай не времена 286-х!

Течёт вода Кубань-реки куда велят большевики.
Re[2]: Функции должны быть компактными
От: dosik Россия www.dosik.ru
Дата: 25.04.16 16:12
Оценка: +2
Здравствуйте, alpha21264, Вы писали:

A>Да и вообще — кому сейчас нужно ловить настолько мелких блох?

A>Чай не времена 286-х!

Ну как сказать ))) Сегодня ты пишешь клиентские десктопные приложения, а завтра на тебе, и ты уже ARM программист, и там рассказывай про блох )))
Re: Функции должны быть компактными
От: vmpire Россия  
Дата: 25.04.16 16:21
Оценка: +1
Здравствуйте, dosik, Вы писали:

D>Т.е. функция должна выполнять лишь одну операцию. Функции, выполняющие несколько операций необходимо дробить на несколько.

Спорное утверждение. Нужно решать в каждом конкретном случае, что лучше.

D>Тогда вопрос: А как же накладные расходы на вызов функции? Ведь вместо того, чтобы продолжить вычисления, теперь нам надо заполнить стек и передать управление по адресу, а по возвращению очистить стек.

Как уже написали, в современных ЯВУ это забота компилятора. Он лучше человека разберётся, что куда инлайнить.

D>Т.е. улучшая читабельность кода мы уменьшаем производительность системы.

Вот это и есть цель: улучшить читаемость

D>Да и как то меня учили, что в функцию необходимо выносить лишь тот код, который может быть вызван из нескольких участков программы. И какой тогда смысл выносить в отдельную функцию код, который будет вызываться только в одном месте?

Неправильно, видимо, учили. Есть такое понятие: "самодокументируемый код".
Чем писать несколько строк кода и к ним комментарий, скажем, "// Check permissions", лучше вынести этот код в отдельный метод с названием CheckPermissions(). Комментарий станет ненужным, не сможет потерять свою актуальность, и, в случае, если функция понадобится в другом месте, коментарий там также не потребуется.
Re: Функции должны быть компактными
От: tdiff  
Дата: 25.04.16 17:34
Оценка: +2
Здравствуйте, dosik, Вы писали:

D>В своей книге Р. Мартин утверждает, что функции необходимо предъявлять всего два требования:

D>1. они должны быть компактными
D>2. они должны быть еще более компактными
D>Т.е. функция должна выполнять лишь одну операцию. Функции, выполняющие несколько операций необходимо дробить на несколько.
D>Тогда вопрос: А как же накладные расходы на вызов функции?

1. Я так подозреваю, что значительная часть целевой аудитории подобных книг пишет программы, в которых производительность не является критичным фактором (не важно, секунду или две будет считаться бизнес-логика, всё равно всё в конечном итоге упирается в БД).
2. Надо стараться не переборщить с "компактизированием", т.к. не всегда разбиение фунции на меньшие улучшает читаемость. Если не ошибаюсь, как раз у Мартина в самом начале, в качестве примера, из понятной программы на 20 строк делается монстр из 5 классов.
Re: Функции должны быть компактными
От: __kot2  
Дата: 25.04.16 18:35
Оценка: +1 :))) :)
Здравствуйте, dosik, Вы писали:
D>Тогда вопрос: А как же накладные расходы на вызов функции? Ведь вместо того, чтобы продолжить вычисления, теперь нам надо заполнить стек и передать управление по адресу, а по возвращению очистить стек. Т.е. улучшая читабельность кода мы уменьшаем производительность системы.
вообще, даже когда ты пишешь на ассемблере, у тебя всегда есть выбор между ф-ией и макросом. современные копиляторы умеют сами оценивать накладные расходы на вызов и решать, что лучше — инлайнить код или реально вызывать его.

D>Да и как то меня учили, что в функцию необходимо выносить лишь тот код, который может быть вызван из нескольких участков программы. И какой тогда смысл выносить в отдельную функцию код, который будет вызываться только в одном месте?

это рекомендации где-то годов 70ых-80. после людям пришло понимание, что программы большие и сложные и соверешнно бесполезные, если в них нельзя разобраться. сначала они начали писать комменты, а потом поняли, что можно давать имена ф-ия так, чтобы по ним было все понятно и без комментов.
любой человек, который до сих пор пишет ф-ии в столбик строк по 30, вставляя туда комменты просто неквалифицирован и его нельзя допускать до написания реального кода
Re: Функции должны быть компактными
От: Pzz Россия https://github.com/alexpevzner
Дата: 25.04.16 18:51
Оценка: 1 (1) +3
Здравствуйте, dosik, Вы писали:

D>Тогда вопрос: А как же накладные расходы на вызов функции? Ведь вместо того, чтобы продолжить вычисления, теперь нам надо заполнить стек и передать управление по адресу, а по возвращению очистить стек. Т.е. улучшая читабельность кода мы уменьшаем производительность системы. Да и как то меня учили, что в функцию необходимо выносить лишь тот код, который может быть вызван из нескольких участков программы. И какой тогда смысл выносить в отдельную функцию код, который будет вызываться только в одном месте?


Ну, есть такая точка зрения, что если выбирать между эффективностью кода и понятностью кода, понятность важнее. Заметим к слову, что даже в программе, в которой эффективкость важна, обычно это касается 10% кода, а остальной код вызывается редко, или упирается во ввод-вывод, а не процессор, и т.п. Кроме того, компилятор часто догадывается поинлайнить функции. И еще, вызов может быть даже дешевле инлайна, поскольку разделение кода на небольшие функции может облегчить жизнь той части компилятора, которая распределяет регистры.

Другой вопрос, что разбиение кода на мелкие функции далеко не всегда облегчает его понимание. Поэтому к этому совету надо относиться критически.
Re: Функции должны быть компактными
От: dosik Россия www.dosik.ru
Дата: 25.04.16 19:19
Оценка:
Отвечу сам себе, поскольку основная масса ответов идентична — не бери на себя работу компилятора, пиши удобочитаемый код, а компилятор сам все заинлайнит.
А что тогда с высоконагруженными приложениями, где кроме как на себя, даже на компилятор положиться нельзя?
Re[2]: Функции должны быть компактными
От: __kot2  
Дата: 25.04.16 19:31
Оценка:
Здравствуйте, dosik, Вы писали:
D>Отвечу сам себе, поскольку основная масса ответов идентична — не бери на себя работу компилятора, пиши удобочитаемый код, а компилятор сам все заинлайнит.
D>А что тогда с высоконагруженными приложениями, где кроме как на себя, даже на компилятор положиться нельзя?
они оптимизированы только в воображении менеджмента и еще может быть hr. в основном работают очень неэффективно
Re[2]: Функции должны быть компактными
От: T4r4sB Россия  
Дата: 25.04.16 19:39
Оценка:
Здравствуйте, __kot2, Вы писали:

__>любой человек, который до сих пор пишет ф-ии в столбик строк по 30, вставляя туда комменты просто неквалифицирован и его нельзя допускать до написания реального кода


30 это много?
Re[2]: Функции должны быть компактными
От: ononim  
Дата: 25.04.16 20:00
Оценка:
A>Да и вообще — кому сейчас нужно ловить настолько мелких блох?
A>Чай не времена 286-х!
Да вот в соседней ветке
Автор: system.console
Дата: 24.04.16
блохами возмущаются
Как много веселых ребят, и все делают велосипед...
Отредактировано 25.04.2016 20:01 ononim . Предыдущая версия .
Re: Функции должны быть компактными
От: vsb Казахстан  
Дата: 25.04.16 20:19
Оценка: +1
В первую очередь код должен быть как можно более читаемым. Если ради этого нужно жертвовать производительностью — надо делать это не задумываясь. И только когда производительность программы станет неудовлетворительной, нужно произвести минимальные ухудшения, чтобы улучшить производительность до приемлемой. Поэтому такими вещами, как накладные расходы на вызовы функций, заморачиваться не нужно.

Есть проекты, в которых производительность важна до той степени, что их части приходится писать на языке ассемблера. Но это очень редкие случаи и погоды они не делают. В 99% случаев именно так.
Re: Функции должны быть компактными
От: Философ Ад http://vk.com/id10256428
Дата: 25.04.16 20:28
Оценка: 53 (2) +3
Здравствуйте, dosik, Вы писали:

D>Тогда вопрос: А как же накладные расходы на вызов функции? Ведь вместо того, чтобы продолжить вычисления, теперь нам надо заполнить стек и передать управление по адресу, а по возвращению очистить стек. Т.е. улучшая читабельность кода мы уменьшаем производительность системы.


О такой мелочёвке нужно можно заботиться только после того как ты отпрофилировал программу. До профайлинга нужно написать удобочитаемый и легко изменяемый код.
Когда после профилировки ты выяснишь, что у тебя какой-нибудь Math.Max() не заинлайнен компилятором, и существует милиард его вызовов, и что от милиарда вызовов никуда не уйти (а именно в этом бОльшая часть оптимизаций и заключается), тогда и заинлайнишь — не раньше.
В ином случае ты рискуешь во время написания отловить блох, а в итоге получить O(n!) там, где должен быть O(n log(n)).
Всё сказанное выше — личное мнение, если не указано обратное.
Отредактировано 26.04.2016 5:21 Философ . Предыдущая версия . Еще …
Отредактировано 25.04.2016 20:29 Философ . Предыдущая версия .
Re[3]: Функции должны быть компактными
От: __kot2  
Дата: 25.04.16 20:38
Оценка:
Здравствуйте, T4r4sB, Вы писали:
TB>Здравствуйте, __kot2, Вы писали:
__>>любой человек, который до сих пор пишет ф-ии в столбик строк по 30, вставляя туда комменты просто неквалифицирован и его нельзя допускать до написания реального кода
TB>30 это много?
слова много и мало они тут неправильные
у меня был знакомый, он тоже писал, писал, потом когда думал, что уже много, создавал новый файл и начинал писать туда. так люди какают, а не пишут программы
функция должна делать одно дело. 30 строк — очень редко когда это что-то прямо одно такое. бывает, но редко. чаще всего там все-таки несколько действий, каждое из которых имеет смысла выделить в отдельную ф-ию.
если все равно непонятно что означает "одно действие", то для начала создайте блоки минимальной видимости переменных, типа

void see_you()
{
  int size = get_size();
  if size > ... 
  do_something(size)

  //а здесь ниже уже нигде size не ипользуется и идет код типа
  call_something()
  do_some_stuff()
  for ( x)
  {
    if ( x > 10)
    {
      print_something();
      x += 2;
    }

    superman = new superman()
    betment = new betment()
    fight(superman, betment)
  }
}

то разумно, чтобы случайно не наткнуться на конфликт имен взять верхий блок в скобки и записать в стиле

void see_you()
{
  {
    int size = get_size();
    if size > ... 
    do_something(size)
  }

  call_something()
  do_some_stuff()

  for ( x : xs)
  {
    if ( x > 10)
    {
      print_something();
      x += 2;
    }

    {
      superman = new superman()
      betment = new betment()
      fight(superman, betment)
    }
  }
}


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

void see_you()
{
  adjust_size()
  call_something()
  do_some_stuff()

  for ( x : xs)
  {
    if ( time_to_so_it(x))
      do_it();

    betment_superman_fight();
  }
}

или даже правильнее будет

void see_you()
{
  adjust_arena_size()
  call_spectators()
  setup_lights()

  betment_fight_for_every_something(xs);
}


причем я не говорю о рефакторинге, никто не мешает так писать сразу. и, разумеется, именя ф-ий не должны называться do_stuff() а должны описывать что конкретно за стафф мы ду.
Re[4]: Функции должны быть компактными
От: T4r4sB Россия  
Дата: 25.04.16 20:46
Оценка: +4
Здравствуйте, __kot2, Вы писали:

__>функция должна делать одно дело. 30 строк — очень редко когда это что-то прямо одно такое. бывает, но редко. чаще всего там все-таки несколько действий, каждое из которых имеет смысла выделить в отдельную ф-ию.


Да скорее задолбаешься контекст функции передавать в подфункции.
Re[3]: Функции должны быть компактными
От: alpha21264 СССР  
Дата: 25.04.16 21:11
Оценка: +5
Здравствуйте, ononim, Вы писали:

A>>Да и вообще — кому сейчас нужно ловить настолько мелких блох?

A>>Чай не времена 286-х!
O>Да вот в соседней ветке
Автор: system.console
Дата: 24.04.16
блохами возмущаются


Я не думаю, что можно набрать 5-10 секунд такими блохами.
Десять миллиардов команд чтобы переключить канал?
Я не думаю, что это от того, что функции короткие.

Течёт вода Кубань-реки куда велят большевики.
Re[3]: Функции должны быть компактными
От: alpha21264 СССР  
Дата: 25.04.16 21:16
Оценка: 2 (1)
Здравствуйте, dosik, Вы писали:

D>Здравствуйте, alpha21264, Вы писали:


A>>Да и вообще — кому сейчас нужно ловить настолько мелких блох?

A>>Чай не времена 286-х!

D>Ну как сказать ))) Сегодня ты пишешь клиентские десктопные приложения, а завтра на тебе, и ты уже ARM программист, и там рассказывай про блох )))


Не чини, пока не сломалось. Вот когда будешь писать для АРМ-а вот тогда... Всё равно дело будет не в блохах.

Течёт вода Кубань-реки куда велят большевики.
Re[5]: Функции должны быть компактными
От: __kot2  
Дата: 25.04.16 21:18
Оценка: -2
Здравствуйте, T4r4sB, Вы писали:
TB>Здравствуйте, __kot2, Вы писали:
__>>функция должна делать одно дело. 30 строк — очень редко когда это что-то прямо одно такое. бывает, но редко. чаще всего там все-таки несколько действий, каждое из которых имеет смысла выделить в отдельную ф-ию.
TB>Да скорее задолбаешься контекст функции передавать в подфункции.
контекст должен быть сгруппирован в структуры
Re[2]: Функции должны быть компактными
От: nigh  
Дата: 25.04.16 21:36
Оценка:
Здравствуйте, dosik, Вы писали:

D>А что тогда с высоконагруженными приложениями, где кроме как на себя, даже на компилятор положиться нельзя?

А что такое "высоконагруженые приложения", пример можно? Или вы чисто теоретически интересуетесь?
Re[2]: Функции должны быть компактными
От: IT Россия linq2db.com
Дата: 25.04.16 22:04
Оценка: +4 :))) :))
Здравствуйте, __kot2, Вы писали:

__>любой человек, который до сих пор пишет ф-ии в столбик строк по 30, вставляя туда комменты просто неквалифицирован и его нельзя допускать до написания реального кода


Считаю такое мнение признаком недопереквалифицированности.
Если нам не помогут, то мы тоже никого не пощадим.
Re[3]: Функции должны быть компактными
От: dosik Россия www.dosik.ru
Дата: 25.04.16 22:45
Оценка:
Здравствуйте, nigh, Вы писали:

N>А что такое "высоконагруженые приложения", пример можно? Или вы чисто теоретически интересуетесь?


Да к примеру тот-же nginx — приложение, способное обрабатывает тысячи и дясятки тысяч запросов в секунду.
Re[4]: Функции должны быть компактными
От: nigh  
Дата: 25.04.16 22:55
Оценка:
Здравствуйте, dosik, Вы писали:

D>Здравствуйте, nigh, Вы писали:


N>>А что такое "высоконагруженые приложения", пример можно? Или вы чисто теоретически интересуетесь?


D>Да к примеру тот-же nginx — приложение, способное обрабатывает тысячи и дясятки тысяч запросов в секунду.


ну там код довольно понятно написан и излишних оптимизаций в виде слишком длинных функций или работы за оптимизатор в нем вроде нет (если не считать вещей вроде парсинга HTTP заголовков, но там оптимизация понятна и вынесена более-менее отдельно)
Re[3]: Функции должны быть компактными
От: __kot2  
Дата: 26.04.16 00:40
Оценка: :)
Здравствуйте, IT, Вы писали:
IT>Считаю такое мнение признаком недопереквалифицированности.
я никогда не пишу код для себя. я всегда его пишу для других. лично мне было иногда бы удобнее все писать в столбик, просто я не хочу издеваться над девелоперами будущего, которые будут это править потом. залог понятного кода — его хорошая структурированность и понятные имена у элементов его структуры. чтобы понять что делает блок кода, не имеющий имени, уже нужно потратить свое время. заставлять людей тратить свое время на твоего кода невежливо
Re[5]: Функции должны быть компактными
От: dosik Россия www.dosik.ru
Дата: 26.04.16 00:44
Оценка:
Здравствуйте, nigh, Вы писали:

N>ну там код довольно понятно написан и излишних оптимизаций в виде слишком длинных функций или работы за оптимизатор в нем вроде нет (если не считать вещей вроде парсинга HTTP заголовков, но там оптимизация понятна и вынесена более-менее отдельно)


Ну nginx изнутри не видел, сказать ни чего не могу. Я просто привел пример по Вашей просьбе.
Re[4]: Функции должны быть компактными
От: MozgC США http://nightcoder.livejournal.com
Дата: 26.04.16 01:53
Оценка: 1 (1) +8
Здравствуйте, __kot2, Вы писали:

__>я никогда не пишу код для себя. я всегда его пишу для других. лично мне было иногда бы удобнее все писать в столбик, просто я не хочу издеваться над девелоперами будущего, которые будут это править потом. залог понятного кода — его хорошая структурированность и понятные имена у элементов его структуры. чтобы понять что делает блок кода, не имеющий имени, уже нужно потратить свое время. заставлять людей тратить свое время на твоего кода невежливо


Почему ты думаешь, что другим разработчикам будет удобнее прыгать по куче маленьких функций при отладке или чтении кода? Меня, например, это напрягает. То, что советует Мартин (функции там у него по 2-5 строк) — это крайность. Такая же крайность, как и функции на сотни строк.

Понятный код — это совсем необязательно маленький размер функций. Функция в 50 строк может быть понятнее, чем функция в 10 строк. It depends, как обычно. Про передачу параметров, тут уже тоже упомянули.

И ты, на основании своего субъективного мнения, так мощно заявляешь, что программистов, пишущих функции длинее 30 строк надо не подпускать к коду? Имхо — это очень сильное, наглое и самоуверенное заявление.
Re[5]: Функции должны быть компактными
От: __kot2  
Дата: 26.04.16 02:13
Оценка: -2 :))
Здравствуйте, MozgC, Вы писали:
MC>Почему ты думаешь, что другим разработчикам будет удобнее прыгать по куче маленьких функций при отладке или чтении кода? Меня, например, это напрягает. То, что советует Мартин (функции там у него по 2-5 строк) — это крайность. Такая же крайность, как и функции на сотни строк.
меня тоже это поначалу раздражжало, когда для того, чтобы узнать по какому критерию вызывается сортировка, нужно перепрыгнуть к ф-ии, когда было бы удобно на месте ее указать. ну это еще до лямбд было. мне не нравилось, что много мелких ф-ий, которые так везде разбросаны-разбросаны и ты прыгаешь по ним. и называются еще как-нить типа sort1, sort2 или less.
но потом понял, что это скорее проблема бедности именования и хреновой структурированности, когда ты не можешь понять, что делает ф-ия по ее названию и тебе надо обязательно лезть внутрь посмотреть и когда вместо композиции из простых и понятных вещей, типа loader или там parser, единственное, на что тебя хватает это на имена в стиле process_part1(), part2() или do_extra_init()

MC>Понятный код — это совсем необязательно маленький размер функций. Функция в 50 строк может быть понятнее, чем функция в 10 строк. It depends, как обычно. Про передачу параметров, тут уже тоже упомянули.

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

MC>И ты, на основании своего субъективного мнения, так мощно заявляешь, что программистов, пишущих функции длинее 30 строк надо не подпускать к коду? Имхо — это очень сильное, наглое и самоуверенное заявление.

не думаю, что вы найдете хоть одну рекоменацию от авторитетного человека, который скажет обратное.
от опытного — да, конечно. я много людей знаю опытных, которые застряли где-то в начале 2000ых в своем подходе к написанию софта. в основном они заняты каким-то саппортом того, что кроме них уже саппортить никто не может. этот проект не будут развивать, его просто закроют на самом деле со временем. когда у нас в одной конторе такой человек ушел на пенсию и передал свои дела и обязанности, то вдруг выяснилось, что все, что он делал можно просто удалить и на самом деле никакого саппорта не нужно, и все уже было замещено новыми сервисами. примерно как с историей поддержки bcd чисел в процессорах.
Re[2]: Функции должны быть компактными
От: gardener  
Дата: 26.04.16 04:41
Оценка:
__>любой человек, который до сих пор пишет ф-ии в столбик строк по 30, вставляя туда комменты просто неквалифицирован и его нельзя допускать до написания реального кода

Может и так. А еще мне кажется человек который так категоричен скорее всего тоже идет туда же.
Re[4]: Функции должны быть компактными
От: Transformerrr  
Дата: 26.04.16 06:27
Оценка:
Здравствуйте, __kot2, Вы писали:

__>Здравствуйте, IT, Вы писали:

IT>>Считаю такое мнение признаком недопереквалифицированности.
__>я никогда не пишу код для себя. я всегда его пишу для других. лично мне было иногда бы удобнее все писать в столбик, просто я не хочу издеваться над девелоперами будущего, которые будут это править потом. залог понятного кода — его хорошая структурированность и понятные имена у элементов его структуры. чтобы понять что делает блок кода, не имеющий имени, уже нужно потратить свое время. заставлять людей тратить свое время на твоего кода невежливо

"чтобы понять что делает блок кода, не имеющий имени" — не любите лямбды?
Re[2]: Функции должны быть компактными
От: Pzz Россия https://github.com/alexpevzner
Дата: 26.04.16 07:10
Оценка: +1
Здравствуйте, dosik, Вы писали:

D>Отвечу сам себе, поскольку основная масса ответов идентична — не бери на себя работу компилятора, пиши удобочитаемый код, а компилятор сам все заинлайнит.

D>А что тогда с высоконагруженными приложениями, где кроме как на себя, даже на компилятор положиться нельзя?

1) Какова доля высоконагруженного кода в высоконагруженном приложении? По моему опыту, очень невелика. Этот код можно писать несколько в другом стиле.
2) Вы точно уверены, что ваше высоконагруженное приложение упирается именно в процессор, а не в сеть, диск и т.п.?
3) Выбор подходящих алгоритмов и структур данных дает, как правило, больший выигрыш, чем низкоуровневая оптимизация
Re[4]: Функции должны быть компактными
От: Pzz Россия https://github.com/alexpevzner
Дата: 26.04.16 07:14
Оценка:
Здравствуйте, dosik, Вы писали:

N>>А что такое "высоконагруженые приложения", пример можно? Или вы чисто теоретически интересуетесь?


D>Да к примеру тот-же nginx — приложение, способное обрабатывает тысячи и дясятки тысяч запросов в секунду.


Говорят, что HTTP-сервер, входящий в стандартную библиотеку языка Go, проигрывает nginx'у на раздаче статического контента всего в два раза. При том, что в отличии от nginx'а, он написан на высокоуровневом языке со сборкой мусора, и никто особо не напрягался оптимизировать его по скорости. И кроме того, у компилятора Go простой и наивный оптимизатор, в отличии от gcc, которым обычно компилируют nginx.
Re[2]: Функции должны быть компактными
От: Pzz Россия https://github.com/alexpevzner
Дата: 26.04.16 07:18
Оценка: +4 -2
Здравствуйте, Философ, Вы писали:

Ф>О такой мелочёвке нужно можно заботиться только после того как ты отпрофилировал программу. До профайлинга нужно написать удобочитаемый и легко изменяемый код.

Ф>Когда после профилировки ты выяснишь, что у тебя какой-нибудь Math.Max() не заинлайнен компилятором, и существует милиард его вызовов, и что от милиарда вызовов никуда не уйти (а именно в этом бОльшая часть оптимизаций и заключается), тогда и заинлайнишь — не раньше.
Ф>В ином случае ты рискуешь во время написания отловить блох, а в итоге получить O(n!) там, где должен быть O(n log(n)).

Заметим, чтобы получился O(n log(n)), об этом надо сразу думать, еще на стадии проектирования.

Т.е., идея, что сначала пишем красиво, потом когда-нибудь оптимизируем, работает в отношении низкоуровневых оптимизаций. Но если вы выбрали на стадии проектирования такое представление данных, что быстрее, чем за время O(n^3) с ними работать не получается, вряд ли вы на поздней стадии получите хотя бы O(n^2)
Re: Функции должны быть компактными
От: Chorkov Россия  
Дата: 26.04.16 09:31
Оценка: +1
Здравствуйте, dosik, Вы писали:

D>В своей книге Р. Мартин утверждает, что функции необходимо предъявлять всего два требования:

D>1. они должны быть компактными
D>2. они должны быть еще более компактными
D>Т.е. функция должна выполнять лишь одну операцию. Функции, выполняющие несколько операций необходимо дробить на несколько.
D>Тогда вопрос: А как же накладные расходы на вызов функции? Ведь вместо того, чтобы продолжить вычисления, теперь нам надо заполнить стек и передать управление по адресу, а по возвращению очистить стек. Т.е. улучшая читабельность кода мы уменьшаем производительность системы. Да и как то меня учили, что в функцию необходимо выносить лишь тот код, который может быть вызван из нескольких участков программы. И какой тогда смысл выносить в отдельную функцию код, который будет вызываться только в одном месте?

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

"Вкусы" компиляторов (и процессоров) сейчас так быстро меняются, что разумнее всего тратить время на оптимизацию алгоритма, а не кода.
Если потратить время на оптимизацию кода, через n-лет все-равно придется этот кусок переписать.
Поэтому занимаясь оптимизацией главное сохранять код понятным.
Re[2]: Функции должны быть компактными
От: dosik Россия www.dosik.ru
Дата: 26.04.16 10:48
Оценка:
Здравствуйте, Chorkov, Вы писали:

C>"Вкусы" компиляторов (и процессоров) сейчас так быстро меняются, что разумнее всего тратить время на оптимизацию алгоритма, а не кода.

C>Если потратить время на оптимизацию кода, через n-лет все-равно придется этот кусок переписать.
C>Поэтому занимаясь оптимизацией главное сохранять код понятным.

Вот тут наверное полностью соглашусь: не все, что хорошо соптимизирует компилятор от Intel, так же хорошо соптимизирует компилятор MS. Аналогично с Clang и GCC. И аналогично для одного и то-же компилятора сегодня и завтра ))) Так что при написании кроссплатформенных вещей возможно следует расставить приоритеты как Вы и указали — оптимизируем код не в ущерб читаемости. Здесь видимо и есть та грань балансировки, которую сам для себя должен найти каждый.
Re[3]: Функции должны быть компактными
От: __kot2  
Дата: 26.04.16 11:19
Оценка: +1
Здравствуйте, gardener, Вы писали:
__>>любой человек, который до сих пор пишет ф-ии в столбик строк по 30, вставляя туда комменты просто неквалифицирован и его нельзя допускать до написания реального кода
G>Может и так. А еще мне кажется человек который так категоричен скорее всего тоже идет туда же.
мы в школе как-то запланировали идти в трехдневный поход. мы народ был уже опытный, брали только самое необходимое, так, пару кг личных вещей и еду заранее всю приготовили, легкие крупу и сухари в основном, поделили между самыми сильными-выносливыми. даже с учетом того, что я нес кучу еды, рюкзак весил всего по-моему 14 кг — смешно просто. поход обещал был легким и приятным. приехали мы на начало маршрута, я выбегаю из автобуса налегке, готовый сейчас прямо за пару часов взбежать на соседнюю гору и тут замечаю девочку, которая выйдя из автобуса стоит держится за лямку огромного рюкзачища, лежаего на земле. она его даже волоком сдвинуть не может. понятно, "мальчики, помогите девочкам, возьмите у кого рюкзаки тяжелые". я отдаю ей свой рюкзак, пытаюсь поднять ее баул и просто вращаюсь вокруг него на одной ноге — он килограмм 60. полный рюкзак картошки и консерв!
делать нечего, нас трое таких счастливцев оказалось и мы поперлись, сильно отставая от группы, небольшими перебежками, согнувшись втрое. пришли вечером на несколько часов позже остальных, жутко матерясь. на утро конечно, выкинули просто эти полтонны картошки, что не сьели и пошли дальше уже по нормальному.
так и прогрммист со своими функциями-спагетями это нечто среднее между маленькой девочкой с мешком картошки и фашистом с гранатой, в зависимости от его должности и степени влияния на проект. он все равно не сможет контролировать сложность проекта сам или же вообще самоустранится и предложит другим разбираться с проблемами.

бывает, что есть производственная необходимость работать с таким кодом и тогда начинается, как Cyberax выражается, санация кода — когда говнокодер отстраняется от проекта, а из проекта все выкидывается по максимуму, упрощается и пишутся нормальные тесты. но это совсем не обязательный этап жизни ПО, надо просто брать с собой в горы проверенных людей, которые понимают, что и как делать надо, а не просто что-то делают, а потом как получится.
Re[5]: Функции должны быть компактными
От: __kot2  
Дата: 26.04.16 11:19
Оценка:
Здравствуйте, Transformerrr, Вы писали:
T>"чтобы понять что делает блок кода, не имеющий имени" — не любите лямбды?
почему, для вещей вроде for_each отлично подходят
Re[3]: Функции должны быть компактными
От: T4r4sB Россия  
Дата: 26.04.16 11:43
Оценка: +1
Здравствуйте, dosik, Вы писали:


D>Вот тут наверное полностью соглашусь: не все, что хорошо соптимизирует компилятор от Intel, так же хорошо соптимизирует компилятор MS. Аналогично с Clang и GCC.


Самая жуть, когда один компилятор вообще не оптимизирует конструкцию, которая единственная даёт верный код на другом компиляторе.
Re: Функции должны быть компактными
От: PM  
Дата: 26.04.16 12:25
Оценка:
Здравствуйте, dosik, Вы писали:

Ещё один аргумент за мелкие функции. В интрепретируемом языке оптимизатор может не сработать из-за большого объема исходного текста функции, как это было в V8: https://top.fse.guru/nodejs-a-quick-optimization-advice-7353b820c92e#.mocj0rnh6

И чинить это в старой версии V8 не стали: https://bugs.chromium.org/p/v8/issues/detail?id=3354 Типа есть костыль в виде опции командной строки, подпирайте им.
Re: Функции должны быть компактными
От: К Тёте  
Дата: 26.04.16 12:44
Оценка:
D>Тогда вопрос: А как же накладные расходы на вызов функции?

Мизерны

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


Зависит от языка и компилятора/интерпретатора. В языках с tail recursion в случае, если последнее возвращаемое значение из функции — это вызов другой функции, стек не будет заполняться и потом очищаться.

D>Т.е. улучшая читабельность кода мы уменьшаем производительность системы.


На сколько? На 0.00001%?

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


Плохо тебя учили. Выносить в функцию надо логические единицы. Иначе подавляющее большинство программ уместится в от силы десяток функций длинной по 50 000 строчек.
На волю, в пампасы!
Re: Функции должны быть компактными
От: Ikemefula Беларусь http://blogs.rsdn.org/ikemefula
Дата: 26.04.16 13:13
Оценка:
Здравствуйте, dosik, Вы писали:

D>В своей книге Р. Мартин утверждает, что функции необходимо предъявлять всего два требования:

D>1. они должны быть компактными
D>2. они должны быть еще более компактными
D>Т.е. функция должна выполнять лишь одну операцию. Функции, выполняющие несколько операций необходимо дробить на несколько.
D>Тогда вопрос: А как же накладные расходы на вызов функции?

Примерно так — если компилер плохой, то ты ему помогаешь. Если хороший, то он помогает тебе.
Но вообще,
0 вкуриваешь проблему, пока всё не станет ясно
1 пишешь, как тебе понятно именно сейчас
2 рефакторишь, когда перестаёшь понимать
3 замеряешь-профилируешь,
а после того, как готов функционал
б когда есть на то основания (нагрузка, тестеры, юзеры, сведения из других источников)
в учитывать надо и абсолютные и относительные величины
г учитывать фазовые переходы вида 'лед превращается в пар минуя воду'
4 оптимизируешь только самое узкое место, его покажут замеры-профилирование
5 тестируешь нагрузкой, когда в требованиях явно или неявно указана эта нагрузка

Когда все 6 пунктов в наличии, и у тебя есть свободное время, можешь подумать про компактность, кошерность, правильность, хорошесть и прочие православности.

PS Когда найдешь того, кто, например, сначала оптимизирует или даже добивается православности, и только потом решает проблему, действуй в соответствии с должностными отношениями.
Re[2]: Функции должны быть компактными
От: Ikemefula Беларусь http://blogs.rsdn.org/ikemefula
Дата: 26.04.16 13:25
Оценка: +1
Здравствуйте, К Тёте, Вы писали:

D>>Т.е. улучшая читабельность кода мы уменьшаем производительность системы.


КТ>На сколько? На 0.00001%?


Иногда и 1000%. Вопрос скорее в частоте встречаемости в разных областях. Если компилятор не делает инлайн, что часто бывает с разными лямбдами, интерфейсами и прочими интересными вещами, то надо помнить, что вызовы таких функций дороже чем, скажем, инкремент.
Соответственно вопрос только в количестве вызовов.
В числодробилках, рендеринге, разных системных тонкостях даже дополнительный инкремент может опаскудить вообще всё. Лямбда, которая содержит такой инкремент, добавит цимеса настолько, что мир покажется холодным и скучным, а Валгалла и Фольквангр отвернутся от тебя.
Re[3]: Функции должны быть компактными
От: К Тёте  
Дата: 26.04.16 15:04
Оценка:
I>Соответственно вопрос только в количестве вызовов.
I>В числодробилках, рендеринге, разных системных тонкостях даже дополнительный инкремент может опаскудить вообще всё. Лямбда, которая содержит такой инкремент, добавит цимеса настолько, что мир покажется холодным и скучным, а Валгалла и Фольквангр отвернутся от тебя.

Соответсвенно, вопрос только в том, где такое критично, а где — нет. Числодробилки, рендеринги и прочая — это опять же сколько, 0.0001% задач? И то, там опять же критичны в первую очередь алгоритмы, а потом — выжимание скорости из железа.

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

Про рендеринг напомнило из смежной области: игростроения. Помнится, в ~2004 (емнип) народ на форумах не мог поверить, что не надо заниматься ручной оптимизацией большинства мест: компилятор проведет оптимизации качественнее.
На волю, в пампасы!
Re[4]: Функции должны быть компактными
От: IT Россия linq2db.com
Дата: 26.04.16 18:00
Оценка: +2
Здравствуйте, __kot2, Вы писали:

IT>>Считаю такое мнение признаком недопереквалифицированности.

__>я никогда не пишу код для себя. я всегда его пишу для других. лично мне было иногда бы удобнее все писать в столбик, просто я не хочу издеваться над девелоперами будущего, которые будут это править потом. залог понятного кода — его хорошая структурированность и понятные имена у элементов его структуры. чтобы понять что делает блок кода, не имеющий имени, уже нужно потратить свое время. заставлять людей тратить свое время на твоего кода невежливо

Я же говорю — недопере. Кто тебе сказал, что десяток мелких методов с невменяемой перекидкой контекста туда-сюда — это понятно и легко поддерживаемо? На самом деле всё что ты здесь пытаешься нам доказать — это то, что твои предпочтения лучше наших. С чего бы?
Если нам не помогут, то мы тоже никого не пощадим.
Re[5]: Функции должны быть компактными
От: __kot2  
Дата: 26.04.16 18:16
Оценка: -2 :)
Здравствуйте, IT, Вы писали:
IT>Я же говорю — недопере. Кто тебе сказал, что десяток мелких методов с невменяемой перекидкой контекста туда-сюда — это понятно и легко поддерживаемо? На самом деле всё что ты здесь пытаешься нам доказать — это то, что твои предпочтения лучше наших. С чего бы?
обычно я пытаюсь что-то доказать, если мне это нужно в работе. разумеется, мне вообще без разницы как там у вас принятно
а мысль, которую я высказал, не о том, что мне что-то удобнее делать, чем остальным, а о том, что существует старый старперский подход, и я тоже когда-то так писал и новый сильно более современный, который для старпера будет непонятен в силу отсутсвия у того навыков хорошего именования (зачем прыгать в ф-ию посмотреть что она делает, если и так по имени можно понять — одно дело у нас ф-ия sort_users, другое дело — sort_users_by_name_ascending). старпер не умеет разбивать задачи на независимые, не умеет разделять контекст, для понимания такого кода нужно держать постоянно в голове состояние всех одновременно используемых переменных и, конечно же, гораздо удобнее иметь их все на одном экране в одном методе. и да, такой код понятен, если в нем разобраться. другое дело, что во-первых, копаться в чужом коде это трата времени, а во-вторых, записанный таким образом код не поддается нормальному тестированию. а, значит, не может быть частью стабильной устойчивой системы. когда-то это было неважно. лет 20 назад. сейчас — важно.
Re[6]: Функции должны быть компактными
От: IT Россия linq2db.com
Дата: 26.04.16 18:22
Оценка: +1
Здравствуйте, __kot2, Вы писали:

__>а мысль, которую я высказал...


Опять лишь штампы, догмы и наклеивания ярлыков. Демагогия, короче.

Вот тебе метод на 300 строк. Иди и сделай его в 30 короче.
Если нам не помогут, то мы тоже никого не пощадим.
Отредактировано 26.04.2016 18:22 IT . Предыдущая версия .
Re[7]: Функции должны быть компактными
От: __kot2  
Дата: 26.04.16 18:55
Оценка:
Здравствуйте, IT, Вы писали:
IT>Вот тебе метод на 300 строк. Иди и сделай его в 30 короче.
вот, такой подход мне нравится, всегда проще что-то обьяснить на конкретном коде
правда, мне непонятно что делает эта ф-ия. упрощает выражения? обьясните на пальцах, пожалста
я конечно могу дать общие рекомендации вынести конкретные случаи в отдельные блоки, чтобы не наступить на типичную ошибку с пролетанием в соседний блок и то, что везде по 100 раз скопипасчено

var exp = func(expr);
if (exp != expr)
return exp;


но я думаю, вы и сами в курсе этого

есть очень простой тест на качество архитектуры кода. когда вы добавляете новую сущность, сколько разных мест вам придется поправить? 1 — отлично. 2 — нормально. больше — плохо. то, что вам при добавлении нового вида expression нужно будет править transform, помимо, я так понимаю, еще десятка других мест явно намекает на непродуманность архитектуры
Re[8]: Функции должны быть компактными
От: IT Россия linq2db.com
Дата: 26.04.16 19:10
Оценка: +1 :)
Здравствуйте, __kot2, Вы писали:

__>правда, мне непонятно что делает эта ф-ия. упрощает выражения? обьясните на пальцах, пожалста


Это типа визитора, только без создания сотен классов.

__>я конечно могу дать общие рекомендации вынести конкретные случаи в отдельные блоки, чтобы не наступить на типичную ошибку с пролетанием в соседний блок и то, что везде по 100 раз скопипасчено


Убрал. Но 10 строк всё равно не получилось. Как же так?

__>но я думаю, вы и сами в курсе этого


В курсе чего?

__>есть очень простой тест на качество архитектуры кода. когда вы добавляете новую сущность, сколько разных мест вам придется поправить? 1 — отлично. 2 — нормально. больше — плохо. то, что вам при добавлении нового вида expression нужно будет править transform, помимо, я так понимаю, еще десятка других мест явно намекает на непродуманность архитектуры


Последний коммит именно это и делает. Добавилась обработка ещё трёх десятков типов выражений. Поменялось только одно место, т.е. это хорошая архитектура. Не спорю.

Теперь всё же мне хочется получить ответ на предыдущий вопрос. Есть метод с хорошей архитектурой, который после устранения копипасты и добавления новых типов выражений составляет 250 строк. Как из него сделать хотя бы строк 10?
Если нам не помогут, то мы тоже никого не пощадим.
Re[9]: Функции должны быть компактными
От: __kot2  
Дата: 26.04.16 19:20
Оценка: -1
Здравствуйте, IT, Вы писали:
__>>правда, мне непонятно что делает эта ф-ия. упрощает выражения? обьясните на пальцах, пожалста
IT>Это типа визитора, только без создания сотен классов.

IT>Теперь всё же мне хочется получить ответ на предыдущий вопрос. Есть метод с хорошей архитектурой, который после устранения копипасты и добавления новых типов выражений составляет 250 строк. Как из него сделать хотя бы строк 10?

как я и говорю, мне непонятно, что конкретно он делает
если т.з. на этот метод звучит как "типа визитора, только без создания сотен классов" то я бы переписал его так:

public static void Visit(this Expression expr, Func<Expression,bool> func)
{
    DontCreateHundredClasses();
}

это полностью удовлетворяют заданию и, как видите, можно и в одну строчку уложить. в принципе, я даже не уверен что и она нужна

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

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

public static void Visit(this Expression expr, Func<Expression,bool> func)
{
    for_each(subexpr : expr.sub_expressions())
        {
          Visit(subexpr, func);
      func(subexpr);
        }
}


ну и имя тогда конечно попнятнее стоит дать, а то никогда не догадаешься, что Visit лезет в подвыражения, пока в метод не посмотришь. соотв-но, четче будет что-то в духе for_every_subexpression_do()
Отредактировано 26.04.2016 19:48 __kot2 . Предыдущая версия . Еще …
Отредактировано 26.04.2016 19:39 __kot2 . Предыдущая версия .
Отредактировано 26.04.2016 19:37 __kot2 . Предыдущая версия .
Отредактировано 26.04.2016 19:27 __kot2 . Предыдущая версия .
Re[10]: Функции должны быть компактными
От: IT Россия linq2db.com
Дата: 26.04.16 19:48
Оценка: +2
Здравствуйте, __kot2, Вы писали:

__>если т.з. на этот метод звучит как "типа визитора, только без создания сотен классов" то я бы переписал его так:


Всё понятно. Как и ожидалось, дойдя до конкретики словоблудие просто приняло другую форму. Было — "я всё знаю", стало — "а покажите тесты".

__>ааа, я, похоже начинаю догадываться. то есть мы хотим просто пройти по всем подвыражения одного выражения и вызывать лямбду? я прав?

__>ну это просто

Это просто, но это не работает. Даже не компилируется. Когда просто, но не работает меня такое не устраивает.
Если нам не помогут, то мы тоже никого не пощадим.
Re[11]: Функции должны быть компактными
От: __kot2  
Дата: 26.04.16 19:54
Оценка: :)
Здравствуйте, IT, Вы писали:
IT>Здравствуйте, __kot2, Вы писали:
__>>если т.з. на этот метод звучит как "типа визитора, только без создания сотен классов" то я бы переписал его так:

IT>Всё понятно. Как и ожидалось, дойдя до конкретики словоблудие просто приняло другую форму. Было — "я всё знаю", стало — "а покажите тесты".

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

IT>Это просто, но это не работает. Даже не компилируется. Когда просто, но не работает меня такое не устраивает.

я несколько лет на C# не писал, синтаксис не помню, хотя не думаю что в этой теме найдется хоть кто-то кто не поймет что я имел в виду. кроме вас, разумеется
Отредактировано 26.04.2016 19:58 __kot2 . Предыдущая версия . Еще …
Отредактировано 26.04.2016 19:55 __kot2 . Предыдущая версия .
Re[12]: Функции должны быть компактными
От: IT Россия linq2db.com
Дата: 26.04.16 20:16
Оценка: +1
Здравствуйте, __kot2, Вы писали:

IT>>Всё понятно. Как и ожидалось, дойдя до конкретики словоблудие просто приняло другую форму. Было — "я всё знаю", стало — "а покажите тесты".

__>я еще в самом начале этой темы писал, что такой код невозможно тестировать, поэтому, разумеется, запрос написать тесты выглядит издевательством.

Размер функции и тестирование это примерно как в огороде бузина, а в Киеве дядька. Не думаю, что если метод в два раза короче, то для него и тесты в два раза лучше.

IT>>Это просто, но это не работает. Даже не компилируется. Когда просто, но не работает меня такое не устраивает.

__>я несколько лет на C# не писал, синтаксис не помню, хотя не думаю что в этой теме найдется хоть кто-то кто не поймет что я имел в виду. кроме вас, разумеется

При чём тут C#? Expression — это стандартный класс фреймворка, для которого нет возможности получить список всех входящих в него Expressions. Т.е. как минимум придётся написать такой метод, к которому возникнут те же самый вопросы. Ибо один только switch превысит предложенный тобой максимум в 30 строк. Но даже если такой метод и был, то он бы нас не устроил, т.к. всегда кроме соображений компактности кода есть ещё и такая злая штука как нефункциональные требования. В данном случае они требуют, чтобы мы не пересоздавали ветку, если она не изменилась.
Если нам не помогут, то мы тоже никого не пощадим.
Re[4]: Функции должны быть компактными
От: Ikemefula Беларусь http://blogs.rsdn.org/ikemefula
Дата: 26.04.16 20:31
Оценка:
Здравствуйте, К Тёте, Вы писали:

I>>Соответственно вопрос только в количестве вызовов.

I>>В числодробилках, рендеринге, разных системных тонкостях даже дополнительный инкремент может опаскудить вообще всё. Лямбда, которая содержит такой инкремент, добавит цимеса настолько, что мир покажется холодным и скучным, а Валгалла и Фольквангр отвернутся от тебя.

КТ>Соответсвенно, вопрос только в том, где такое критично, а где — нет. Числодробилки, рендеринги и прочая — это опять же сколько, 0.0001% задач? И то, там опять же критичны в первую очередь алгоритмы, а потом — выжимание скорости из железа.


Пудозреваю, в твоих проектах это не надо делать.

Например, когда вызов функции у тебя асинхронный, это само по себе дает счет на милисекунды. Что характерно, компилятор тут вообще не помощник. Если руками заинлайнить, то профит вообще сказочный. И это ничего особенного — фронтенд, бакенд или мобайл или десктоп.

Перформанс это не "надо-не надо" а "какие возможности даёт". Алгоритмы — это и ежу понятно. Константы во всяких O(log(N)) никто не отменял, O(K*N^2) может работать быстрее, нежели O(M*log(N)). Или так — сортировка пузырьком, когда данные отсортированы, работает быстрее квиксорта и мержсорта.

То есть, вне зависимости от хорошести алгоритма, потери на вызовах могут быть и 1000% и больше.
Re[13]: Функции должны быть компактными
От: __kot2  
Дата: 26.04.16 20:34
Оценка:
Здравствуйте, IT, Вы писали:
IT>Здравствуйте, __kot2, Вы писали:
IT>>>Всё понятно. Как и ожидалось, дойдя до конкретики словоблудие просто приняло другую форму. Было — "я всё знаю", стало — "а покажите тесты".
__>>я еще в самом начале этой темы писал, что такой код невозможно тестировать, поэтому, разумеется, запрос написать тесты выглядит издевательством.
IT>Размер функции и тестирование это примерно как в огороде бузина, а в Киеве дядька. Не думаю, что если метод в два раза короче, то для него и тесты в два раза лучше.
а каким вы образом будете тестировать гигантский switch где сгруппировано всю кучками? будете писать отдельный тест для каждого значения case? для одного из класса? или все-таки для каждого класса таких значений?
тесты говнокода всегда пытаются описать что говнокод делает, когда тест нормального кода описывает что код должен делать

IT>>>Это просто, но это не работает. Даже не компилируется. Когда просто, но не работает меня такое не устраивает.

__>>я несколько лет на C# не писал, синтаксис не помню, хотя не думаю что в этой теме найдется хоть кто-то кто не поймет что я имел в виду. кроме вас, разумеется
IT>При чём тут C#? Expression — это стандартный класс фреймворка, для которого нет возможности получить список всех входящих в него Expressions. Т.е. как минимум придётся написать такой метод, к которому возникнут те же самый вопросы. Ибо один только switch превысит предложенный тобой максимум в 30 строк. Но даже если такой метод и был, то он бы нас не устроил, т.к. всегда кроме соображений компактности кода есть ещё и такая злая штука как нефункциональные требования. В данном случае они требуют, чтобы мы не пересоздавали ветку, если она не изменилась.
я ничего про ветку не понял. вот, допустим, я что-то добавил-поменял в выражениях. как мне удостовериться, что ничего старого не поломалось, а новое работает?
Re[14]: Функции должны быть компактными
От: IT Россия linq2db.com
Дата: 26.04.16 21:45
Оценка: +1
Здравствуйте, __kot2, Вы писали:

__>а каким вы образом будете тестировать гигантский switch где сгруппировано всю кучками? будете писать отдельный тест для каждого значения case? для одного из класса? или все-таки для каждого класса таких значений?


а каким вы образом будете тестировать гигантский цикл? будуте писать отдельный тест для каждой итерации?

__>тесты говнокода всегда пытаются описать что говнокод делает, когда тест нормального кода описывает что код должен делать


Глубокая мысль. Если её упростить, то получится так: дважды два равно четыре, когда трижды три равно девять.

__>я ничего про ветку не понял. вот, допустим, я что-то добавил-поменял в выражениях. как мне удостовериться, что ничего старого не поломалось, а новое работает?


Ты опять про тесты? Давай может вернёмся к тому как ты сейчас лихо из 250 строк предложенного кода сделаешь 10?
Если нам не помогут, то мы тоже никого не пощадим.
Re[15]: Функции должны быть компактными
От: __kot2  
Дата: 26.04.16 22:02
Оценка: -1
Здравствуйте, IT, Вы писали:
IT>Здравствуйте, __kot2, Вы писали:
__>>а каким вы образом будете тестировать гигантский switch где сгруппировано всю кучками? будете писать отдельный тест для каждого значения case? для одного из класса? или все-таки для каждого класса таких значений?
IT>а каким вы образом будете тестировать гигантский цикл? будуте писать отдельный тест для каждой итерации?
тут, разумеется, понадобится два теста. на то, что метод вызывается нужное число и раз и корректность работы метода непосредственно

__>>тесты говнокода всегда пытаются описать что говнокод делает, когда тест нормального кода описывает что код должен делать

IT>Глубокая мысль. Если её упростить, то получится так: дважды два равно четыре, когда трижды три равно девять.
нет. просто когда понимаешь, что потом это еще и тестировать надо, то стараешься писать совсем по другому

__>>я ничего про ветку не понял. вот, допустим, я что-то добавил-поменял в выражениях. как мне удостовериться, что ничего старого не поломалось, а новое работает?

IT>Ты опять про тесты? Давай может вернёмся к тому как ты сейчас лихо из 250 строк предложенного кода сделаешь 10?
я уже привел свое решение

public static void for_every_subexpression_do(this Expression expr, Func<Expression,bool> func)
{
    for_each(subexpr : expr.sub_expressions())
        {
          Visit(subexpr, func);
          func(subexpr);
        }
}

наверное, правильнее будет вставить
Visit(expr, func);

на самый верх, но это зависит так же от того, что мы понимаем под подвыражением

6 строчек кода. 7 если разделитесь для красоты добавить

код сразу становится легко тестируемым и для того, чтобы его понять, не нужно 20 минут гаданий
Отредактировано 26.04.2016 22:04 __kot2 . Предыдущая версия .
Re[16]: Функции должны быть компактными
От: IT Россия linq2db.com
Дата: 26.04.16 22:39
Оценка:
Здравствуйте, __kot2, Вы писали:

__>я уже привел свое решение


Я уже отвечал, что это псевдорешение не работает.
Если нам не помогут, то мы тоже никого не пощадим.
Re[2]: Функции должны быть компактными
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 26.04.16 23:25
Оценка: +1
Здравствуйте, dosik, Вы писали:

D>А что тогда с высоконагруженными приложениями, где кроме как на себя, даже на компилятор положиться нельзя?


С высоконагруженными приложениями вообще относительно пофик на удельное быстродействие, там неизмеримо важнее масштабируемость.
... << RSDN@Home 1.0.0 alpha 5 rev. 0 on Windows 8 6.2.9200.0>>
AVK Blog
Re[6]: Функции должны быть компактными
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 26.04.16 23:25
Оценка:
Здравствуйте, __kot2, Вы писали:

__>не думаю, что вы найдете хоть одну рекоменацию от авторитетного человека, который скажет обратное.

__>от опытного — да, конечно. я много людей знаю опытных, которые застряли где-то в начале 2000ых

Скажи, а тут, на rsdn, есть для тебя кто то авторитетный, или все застряли в начале 2000-х?
... << RSDN@Home 1.0.0 alpha 5 rev. 0 on Windows 8 6.2.9200.0>>
AVK Blog
Re[4]: Функции должны быть компактными
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 26.04.16 23:26
Оценка:
Здравствуйте, __kot2, Вы писали:

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


А можно посмотреть на твой собственный код?
... << RSDN@Home 1.0.0 alpha 5 rev. 0 on Windows 8 6.2.9200.0>>
AVK Blog
Re[17]: Функции должны быть компактными
От: __kot2  
Дата: 26.04.16 23:51
Оценка: :)
Здравствуйте, IT, Вы писали:
IT>Здравствуйте, __kot2, Вы писали:
__>>я уже привел свое решение
IT>Я уже отвечал, что это псевдорешение не работает.
ну не работает, так не работает. в конце концов я так до конца и не уверен, насчет того, что же делает эта ф-ия
Re[7]: Функции должны быть компактными
От: __kot2  
Дата: 26.04.16 23:52
Оценка: -1 :)
Здравствуйте, AndrewVK, Вы писали:
__>>не думаю, что вы найдете хоть одну рекоменацию от авторитетного человека, который скажет обратное.
__>>от опытного — да, конечно. я много людей знаю опытных, которые застряли где-то в начале 2000ых
AVK>Скажи, а тут, на rsdn, есть для тебя кто то авторитетный, или все застряли в начале 2000-х?
тут много грамотного народа. я был лучшего мнения о отметившихся тут, они сами признались, что спагетти это нормально
Re[4]: Функции должны быть компактными
От: gardener  
Дата: 26.04.16 23:58
Оценка: +1 :)
А вот интересно зачем ты такой говнокод в своем посте развел.
Куча левого текста, пунктуация кривая, предложения не выделяются, мыслей нет.
И нет, это не придирки к грамматическим ошибкам. Мне прсто удивительно как человек так болеющий по поводу говнокода и при этом так ужасно оформляет свою письменную речь. Это компенсация?
Re[5]: Функции должны быть компактными
От: __kot2  
Дата: 26.04.16 23:58
Оценка:
Здравствуйте, AndrewVK, Вы писали:
AVK>А можно посмотреть на твой собственный код?
публичных репозиториев моих нет. я тут выкладывал как-то код брутфорсера паролей, но он уже 8милетней давности и мне сейчас кажется корявенько сделанным.
да мне не сложно написать код для конкретного примера. вот IT уперся, что мое решение его не устраивает.
я могу раскрыть свой пойнт на любой другой ф-ии, если есть желание. давайте ссылку на код, я покажу, как я считаю нужным написать. можно даже проголосовать кто за, кто против.
Re[5]: Функции должны быть компактными
От: __kot2  
Дата: 27.04.16 00:07
Оценка:
Здравствуйте, gardener, Вы писали:
G>А вот интересно зачем ты такой говнокод в своем посте развел.
G>Куча левого текста, пунктуация кривая, предложения не выделяются, мыслей нет.
G>И нет, это не придирки к грамматическим ошибкам. Мне прсто удивительно как человек так болеющий по поводу говнокода и при этом так ужасно оформляет свою письменную речь. Это компенсация?
это ровно то, что я сказал бы в личном разговоре. именно поэтому я не выделяю начало предложений большими буквами, так как в разговоре мы тоже прекрасно без этого обходимся. логично же!
Re[6]: Функции должны быть компактными
От: gardener  
Дата: 27.04.16 00:13
Оценка:
__>это ровно то, что я сказал бы в личном разговоре. именно поэтому я не выделяю начало предложений большими буквами, так как в разговоре мы тоже прекрасно без этого обходимся. логично же!

А какая связь между личным разговором и письменное речью? Или это прием потока сознания?
Re[18]: Функции должны быть компактными
От: IT Россия linq2db.com
Дата: 27.04.16 00:17
Оценка: +1 :))) :))
Здравствуйте, __kot2, Вы писали:

__>ну не работает, так не работает.


Пусть не работает. Главное, чтобы было 10 строк.
Если нам не помогут, то мы тоже никого не пощадим.
Re[4]: Функции должны быть компактными
От: IT Россия linq2db.com
Дата: 27.04.16 00:39
Оценка: 29 (3) :))
Здравствуйте, __kot2, Вы писали:

__>так и прогрммист со своими функциями-спагетями это нечто среднее между маленькой девочкой с мешком картошки и фашистом с гранатой




Настоящая история про фашиста с гранатой.

Был у нас на одном проекте в IBM архитектор, любитель паттернов и мелких недо функций. Потребовалось нам как-то реализовать простенький отчёт на одну страницу, полей на 30-ть. Задача простая — есть набор входных данных, простых, набор полей без списков, нужно сформировать текст вида

@"
First Name: {0}
Last Name: {1}
"


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

Понять как этот говнокод работал было решительно невозможно. Соответственно, баги, проблемы расширения и сопровождения, задержки сроков и т.п.

Happy End:

Через пару месяцев по совокупности содеянного чувака разжаловали в девелоперы. Больше визиторов и недо функций на проекте не видели. Команда сдала проект в срок с опережением графика и выиграла в капиталистическом соревновании.
Если нам не помогут, то мы тоже никого не пощадим.
Re[6]: Функции должны быть компактными
От: IT Россия linq2db.com
Дата: 27.04.16 00:59
Оценка:
Здравствуйте, __kot2, Вы писали:

__>да мне не сложно написать код для конкретного примера. вот IT уперся, что мое решение его не устраивает.


Ещё раз объясняю. Твоё решение сначала не работает, а уже потом не устраивает.
Если нам не помогут, то мы тоже никого не пощадим.
Re[5]: Функции должны быть компактными
От: __kot2  
Дата: 27.04.16 01:18
Оценка:
Здравствуйте, IT, Вы писали:
IT>Прямого кода в одну функцию строк на двести с проверками. Чувак не нашёл какой здесь паттерн можно применить, а так как у него по-умолчанию, если не могу применить никакого паттерна, то применяю визитор, именно его бодрячком и применил. В результате образовалось 77 классов, в каждом по одному-два мелких метода.
стыдно признаться, но никогда в жизни не писал визиторов, фасадов, абстактгых фабрик и прочей дребедени
смысл современного проектирования в том, что код должен быть минимальным, удовлетворяющим требованиям.
работал я с человеком, который тоже наплодил всяких паттернов не в тему. было это в 2003ем году по-моему. думали, удивить меня чем-то чтоли?
невнеразумительные спагетти с ничего не говорящими названиями тоже ничего хорошего из себя не представляют. это просто другой сорт одного и того же. нет, честно, я так тоже писал. в 9ом-10ом классе школы строчил ф-ии строк по 200-300 шириной в два экрана. с тех пор, правда, за 18 лет, понял, что есть способы получше. это не то, что я типа такой мегамодный, просидел штанами стул и постиг просветление, а про то, что я полностью в курсе всех плюсов и минусов обсуждаемых тут подходов и удивлен, что кое-кто застрял в прошлом в плане проектирования, когда пора бы уже сказать лапше нет и сделать левелап
Отредактировано 27.04.2016 1:22 __kot2 . Предыдущая версия .
Re[6]: Функции должны быть компактными
От: MozgC США http://nightcoder.livejournal.com
Дата: 27.04.16 01:34
Оценка: +1
Здравствуйте, __kot2, Вы писали:

__>а про то, что я полностью в курсе всех плюсов и минусов обсуждаемых тут подходов и удивлен, что кое-кто застрял в прошлом в плане проектирования, когда пора бы уже сказать лапше нет и сделать левелап


Дык, мы вроде как тут ждём, когда ты перепишешь тот пример от IT хотя бы на 30 строк, чтобы мы поучились и получили левелап?...
(Ну и это... один маленький момент... еще надо чтобы код работал, сорри конечно за придирки...)
Re[7]: Функции должны быть компактными
От: __kot2  
Дата: 27.04.16 01:52
Оценка: :)
Здравствуйте, MozgC, Вы писали:
MC>Дык, мы вроде как тут ждём, когда ты перепишешь тот пример от IT хотя бы на 30 строк, чтобы мы поучились и получили левелап?...
MC>(Ну и это... один маленький момент... еще надо чтобы код работал, сорри конечно за придирки...)
не, ну если прямо совсем не понятны предлагаемые мною изменения, то, к сожалению, обьяснять придется очень долго, начиная с самых основ, там, что такое дерево, его обход, префиксный там, постфиксный, что такое рекурсия, потом мне понадобится выкачать все исходники, собрать, переписать несколько классов, написать тесты, проверить. разумеется, я этого делать не буду. я думал мы тут обсуждаем все-таки архитектуру и мне не нужно разжевывать такие элементарные вещи. и более того, мне лично с этого ничего не надо. не понятно, что я имею в виду и ладно, я не против.
Re[8]: Функции должны быть компактными
От: MozgC США http://nightcoder.livejournal.com
Дата: 27.04.16 02:30
Оценка: 94 (4) +5
Здравствуйте, __kot2, Вы писали:

__> не понятно, что я имею в виду и ладно, я не против.


Ну вот... а я хотел левелап...

А если серьезно, я пару-тройку лет назад пробовал подход Мартина (микро-функции), и, честно скажу, мне даже в чем-то это понравилось, — код с одной стороны действительно становился понятнее. Но:
1) Иногда функцию просто не стоит уменьшать, с ней и так всё в порядке, даже если её размер противоречит Теории Мартина-Кота2 (превышает 5-30 строк).
2) С одной стороны код становился понятнее; с другой стороны, при чтении кода приходилось прыгать по куче функций, чтобы понять, что происходит. Так же часто приходилось пользоваться решарперовским Find Usages, чтобы посмотреть откуда вызывается эта микро-функция, только чтобы увидеть, что вызывается она из одного места. При отладке тоже не нравилось прыгать по куче микро-функций. Не конец света, конечно, но не айс.

В результате я как-то забросил подход с микро-функциями и все эти субъективные лимиты (в 5-10 строк, полэкрана, 1 экран, 2 экрана, 30 строк и т.д.) и тупо продолжил писать по ситуации: вижу что лучше сделать extract method — делаю, если функция на 1-2 экрана отлично читается линейно или её сложно уменьшить — оставляю как есть.

PS. Для тех, кто еще не решил для себя, каким размером ограничивать функции и стоит ли это делать: можете просто попробовать подход с маленькими функциями в течение нескольких месяцев и сами для себя решите — нравится вам это или нет.
Отредактировано 27.04.2016 2:42 MozgC . Предыдущая версия .
Re[6]: Функции должны быть компактными
От: IT Россия linq2db.com
Дата: 27.04.16 03:24
Оценка:
Здравствуйте, __kot2, Вы писали:

__>это не то, что я типа такой мегамодный


Мегамодный? Я бы назвал это старомодный, но рука не поднимается. Это дремучая затхлость из тех пещерных веков, когда экраны были по 80 символов в ширину и 25 в высоту и для задействования горизонтального скролинга нужно было восемь пальцев. Тогда 30 строк было не просто много, а очень много. Сейчас такое можно воспроизвести только на мобилке. Ты не на мобилке случайно программируешь? Тогда твоё увлечение микро функциями будет понятно.
Если нам не помогут, то мы тоже никого не пощадим.
Re[9]: Функции должны быть компактными
От: __kot2  
Дата: 27.04.16 03:28
Оценка:
Здравствуйте, MozgC, Вы писали:
MC>1) Иногда функцию просто не стоит уменьшать, с ней и так всё в порядке, даже если её размер противоречит Теории Мартина-Кота2 (превышает 5-30 строк).
я против измерения сложности ф-ии строками. просто одна ф-ия занимается одним делом. бывают такие ф-ии по 30 строк, которые неразумно бить на части, но их очень мало в общем кол-ве. абсолютное большинство безо всяких усилий укладывается в 10 строк. никто не заставляет запихивать ф-ию в 10 строк, это делается совершенно ествественно, просто даже добавить в нее нечего. например, мы открываем файл, проверяем статус, передвигаемся на его конец, возвращаем позицию. все. любая другая операция тут будет лишней.

MC>2) С одной стороны код становился понятнее; с другой стороны, при чтении кода приходилось прыгать по куче функций, чтобы понять, что происходит. Так же часто приходилось пользоваться решарперовским Find Usages, чтобы посмотреть откуда вызывается эта микро-функция, только чтобы увидеть, что вызывается она из одного места. При отладке тоже не нравилось прыгать по куче микро-функций. Не конец света, конечно, но не айс.

маленькие ф-ии это еще полдела. они должны быть названы так, чтобы по названию было понятно, что она делает, не заглядывая внутрь. и сами классы тоже должны быть маленькими и называться не datahelper, а так, чтобы вы могли понять что делает этот класс, не заглядывая в него. так, например, ф-ия работы с временной зоной не должна находиться внутри utils.cs и являться частью класса datetimehelper, она должна называться timezone и находиться в модуле timezone или хотя бы datetime и вам не придется никуда прыгать по коду, так как класс timezone описывает временную зону и странно ожидать там что-то другое

MC>В результате я как-то забросил подход с микро-функциями и все эти субъективные лимиты (в 5-10 строк, полэкрана, 1 экран, 2 экрана, 30 строк и т.д.) и тупо продолжил писать по ситуации: вижу что лучше сделать extract method — делаю, если функция на 1-2 экрана отлично читается линейно или её сложно уменьшить — оставляю как есть.

а тесты?

MC>PS. Для тех, кто еще не решил для себя, каким размером ограничивать функции и стоит ли это делать: можете просто попробовать подход с маленькими функциями в течение нескольких месяцев и сами для себя решите — нравится вам это или нет.

нужно не пробовать подход с маленькими ф-иями, а подход с написанием юнит-тестов. вы быстро выясните, что при привычном подходе вам тестов придется писать еще и больше кода и, постепенно поймете, как разбить все на маленькие назависимые, скомпонованные между собой модули, чтобы изменения в одном не тянули изменений в другом. но скорее всего вы плюнете на эту задумку и оставите только функциональные тесты, время выполнения которых постепенно докатится до 4 часов на коммит и вы, наконец, поймете, в чем разница между юнит тестами и функциональными.
Re[7]: Функции должны быть компактными
От: __kot2  
Дата: 27.04.16 03:53
Оценка:
Здравствуйте, IT, Вы писали:
IT>Мегамодный? Я бы назвал это старомодный, но рука не поднимается. Это дремучая затхлость из тех пещерных веков, когда экраны были по 80 символов в ширину и 25 в высоту и для задействования горизонтального скролинга нужно было восемь пальцев. Тогда 30 строк было не просто много, а очень много. Сейчас такое можно воспроизвести только на мобилке. Ты не на мобилке случайно программируешь? Тогда твоё увлечение микро функциями будет понятно.
если что-то куда-то влазит, то совсем не обязательно это туда запихивать. это еще из физиологии известно
человек он не мегагений, не надо ему голову морочить, заставляя по строчкам исследовать код, как древние письмена, пытаясь по набору разрозненных вещей составить целую картину. картина должна быть ясна сразу, буквально по названиям классов, что, зачем, как делается.
Re[8]: Функции должны быть компактными
От: IT Россия linq2db.com
Дата: 27.04.16 05:22
Оценка: :)
Здравствуйте, __kot2, Вы писали:

__>потом мне понадобится выкачать все исходники, собрать, переписать несколько классов,


Ты очень невнимательный. Я тебе уже говорил, что Expressions — это часть .NET Framework. Выкачать его исходники ты сейчас сможешь и даже собрать. Но вот переписать несколько классов тебе вряд ли кто-нибудь позволит из Microsoft. По крайней мере до тех пор пока ты не научишься писать компилируемый код.
Если нам не помогут, то мы тоже никого не пощадим.
Re[8]: Функции должны быть компактными
От: IT Россия linq2db.com
Дата: 27.04.16 05:25
Оценка:
Здравствуйте, __kot2, Вы писали:

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


Всё так. Только при чём тут 'микро функции рулят'?
Если нам не помогут, то мы тоже никого не пощадим.
Re[6]: Функции должны быть компактными
От: Ziaw Россия  
Дата: 27.04.16 05:48
Оценка:
Здравствуйте, __kot2, Вы писали:

__>существует старый старперский подход, и я тоже когда-то так писал и новый сильно более современный, который для старпера будет непонятен в силу отсутсвия у того навыков хорошего именования


в мемориз
Re: Функции должны быть компактными
От: Privalov  
Дата: 27.04.16 07:40
Оценка: -1 :)
Здравствуйте, dosik, Вы писали:

D>Тогда вопрос: А как же накладные расходы на вызов функции?


А еще не нужно давать объектам, используемым в программе, длинные имена. Накладные расходы на печатание увеличиваются. При компиляции память занимают.
Re[8]: Функции должны быть компактными
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 27.04.16 09:23
Оценка: +1
Здравствуйте, __kot2, Вы писали:

AVK>>Скажи, а тут, на rsdn, есть для тебя кто то авторитетный, или все застряли в начале 2000-х?

__>тут много грамотного народа.

Например?

__>они сами признались, что спагетти это нормально


Ты неверно понимаешь что такое спагетти.
... << RSDN@Home 1.0.0 alpha 5 rev. 0 on Windows 8 6.2.9200.0>>
AVK Blog
Re[2]: Функции должны быть компактными
От: dosik Россия www.dosik.ru
Дата: 27.04.16 09:58
Оценка:
Здравствуйте, Privalov, Вы писали:

P>Здравствуйте, dosik, Вы писали:


D>>Тогда вопрос: А как же накладные расходы на вызов функции?


P>А еще не нужно давать объектам, используемым в программе, длинные имена. Накладные расходы на печатание увеличиваются. При компиляции память занимают.


Вот только Вас с Вашими шутками тут и ждали. Дождались!!! Все, можно закрывать тему!
Re[10]: Функции должны быть компактными
От: WolfHound  
Дата: 27.04.16 10:07
Оценка:
Здравствуйте, __kot2, Вы писали:

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

А вот скажи мне как писать тесты до кода если задача ставится так:
Сделай хрень, которая должна делать примерно то-то. Возможны небольшие отклонения от идеального решения, ибо идеальное решение будет работать дольше жизни вселенной.
При этом нужно уложится в 50 миллисекунд. А лучше в 10.

Имей в виду что при решении таких задач весь код несколько раз переписывается.

__>но скорее всего вы плюнете на эту задумку и оставите только функциональные тесты, время выполнения которых постепенно докатится до 4 часов на коммит и вы, наконец, поймете, в чем разница между юнит тестами и функциональными.

Запускать все тесты на каждый коммит весьма странная затея.
Полностью тестировать нужно только перед отправкой кода в главную ветку. А рабочие ветки могут даже не компилироваться. И ничего плохого в этом нет.
... << RSDN@Home 1.2.0 alpha 5 rev. 62>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[3]: Функции должны быть компактными
От: Privalov  
Дата: 27.04.16 10:39
Оценка: +1
Здравствуйте, dosik, Вы писали:

P>>А еще не нужно давать объектам, используемым в программе, длинные имена. Накладные расходы на печатание увеличиваются. При компиляции память занимают.


D>Вот только Вас с Вашими шутками тут и ждали. Дождались!!! Все, можно закрывать тему!


Дак ведь тоже экономия ресурсов, только не при выполнении, а при сборке.

У всего этого ноги растут в 70-е — 80-е годы, эпоху расцвета ЕС ЭВМ. Насколько я помню, именно тогда не рекомендовали делать подпрограммы из-за дороговизны их вызова. Я буквально слегка эту эпоху зацепил, углубиться не успел. У ЕС ЭВМ подготовка к вызову была, насколько я знаю, дорогой процедурой. Там не было аппаратного стека, подобного PC-шному. Поэтому нужно быдо выделить память, сохранить туда все, что нужно, позвать подпрограмму, восстановить все после окончания ее работы.

Мне приходилось видеть числодробилки, написанные в те годы на Фортране 4. Некоторые из ник представляли из себя ровно то, о чем Вы пишете: 5000 строк находятся в главной программе. Работало быстро, но прочитать это было невозможно. В том числе, кстати, из-за имен. Тогдашние компиляторы Фортрана распознавали в имент только 6 символов, игнорируя остальные. Например, MYNAME1 и MYNAME2 компилятором не различались. Поэтому никто не заморачивался с ними. Даже наоборот: используя короткое имя, снижалась вероятность ошибки. Такие дела.
Re[9]: Функции должны быть компактными
От: __kot2  
Дата: 27.04.16 12:00
Оценка:
Здравствуйте, IT, Вы писали:
IT>Ты очень невнимательный. Я тебе уже говорил, что Expressions — это часть .NET Framework. Выкачать его исходники ты сейчас сможешь и даже собрать. Но вот переписать несколько классов тебе вряд ли кто-нибудь позволит из Microsoft. По крайней мере до тех пор пока ты не научишься писать компилируемый код.
то есть стандартный класс нам диктует как писать код?
если ваша абстракция не полностью соотв-ет стандартному классу, то все, ничего нельзя поделать?

IT>Всё так. Только при чём тут 'микро функции рулят'?

для того, чтобы понять что делает блок кода, нужно изучить его построчно.
чтобы не изучать дважды можно выделить его в блок и написать короткий коммент сверху, что он и как реально делает
ну и совсем чтобы довести идею стоит коммент превратить в имя ф-ии и вынести этот блок в отдельую ф-ию
Re[11]: Функции должны быть компактными
От: __kot2  
Дата: 27.04.16 12:09
Оценка:
Здравствуйте, WolfHound, Вы писали:
__>>нужно не пробовать подход с маленькими ф-иями, а подход с написанием юнит-тестов. вы быстро выясните, что при привычном подходе вам тестов придется писать еще и больше кода и, постепенно поймете, как разбить все на маленькие назависимые, скомпонованные между собой модули, чтобы изменения в одном не тянули изменений в другом.
WH>А вот скажи мне как писать тесты до кода если задача ставится так:
WH>Сделай хрень, которая должна делать примерно то-то. Возможны небольшие отклонения от идеального решения, ибо идеальное решение будет работать дольше жизни вселенной.
WH>При этом нужно уложится в 50 миллисекунд. А лучше в 10.
вот меня кстати удивляет когда люди пишут такие задачи без юнит тестов, по крайней мере на сам алгоритм.
потом чего-нить поломается, они "ща" и как слесарь с сигареткой в зубах, лезут в щиток, там что-то подогнут и "ну все, заводи заново"
разумеется все типичные и переломные точки обработки должны собираться в коллекцию и тестироваться.

WH>Имей в виду что при решении таких задач весь код несколько раз переписывается.

вы мне просто мою работу описываете. если кто-то придет и скажет "я пеерписал весь код, теперь он работает правильно и быстро", я скажу — "докажи!". учитывайте, что даже x264 кодек знаменит тем, что дает битые кадры периодически, хотя вроде бы тысячи людей постоянно гоняют на нем какие-то свои тесты.

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

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

__>>но скорее всего вы плюнете на эту задумку и оставите только функциональные тесты, время выполнения которых постепенно докатится до 4 часов на коммит и вы, наконец, поймете, в чем разница между юнит тестами и функциональными.

WH>Запускать все тесты на каждый коммит весьма странная затея.
WH>Полностью тестировать нужно только перед отправкой кода в главную ветку. А рабочие ветки могут даже не компилироваться. И ничего плохого в этом нет.
и отправда в главную ветку это целое эпохальное событие с неожиданной развязкой? батюшку приглашаете для освящения сервера, дабы повысить шансы, что ничего не сломается? никаких других вариантов пока не придумали?
Отредактировано 27.04.2016 12:59 __kot2 . Предыдущая версия . Еще …
Отредактировано 27.04.2016 12:36 __kot2 . Предыдущая версия .
Re[5]: Функции должны быть компактными
От: К Тёте  
Дата: 27.04.16 12:15
Оценка:
КТ>>Соответсвенно, вопрос только в том, где такое критично, а где — нет. Числодробилки, рендеринги и прочая — это опять же сколько, 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)) даст прирост производительности и быстродействия гораздо более ощутимый, чем погоня за инлайнингом функций
На волю, в пампасы!
Re[9]: Функции должны быть компактными
От: К Тёте  
Дата: 27.04.16 12:25
Оценка:
MC>2) С одной стороны код становился понятнее; с другой стороны, при чтении кода приходилось прыгать по куче функций, чтобы понять, что происходит. Так же часто приходилось пользоваться решарперовским Find Usages, чтобы посмотреть откуда вызывается эта микро-функция, только чтобы увидеть, что вызывается она из одного места. При отладке тоже не нравилось прыгать по куче микро-функций. Не конец света, конечно, но не айс.

Имхо, микро-мини-функции хороши в пределах одного модуля, экспортирующего свой функционал в виде одного-двух API-вызовов.

Тогда получается вполне хорошо:
— достаточно крупный кусок самодостаточной логики помешается в модуль
— внутри себя разбивается на небольшие функции, которые отвечают за какие-то внутренние логические куски
— извне это выглядит, как черная коробка с внятным API

Понятно, что это — утопия, но, пытаясь к такой утопии прийти, можно получить нормальный удобоваримый код.
На волю, в пампасы!
Re[12]: Функции должны быть компактными
От: WolfHound  
Дата: 27.04.16 13:36
Оценка:
Здравствуйте, __kot2, Вы писали:

WH>>Сделай хрень, которая должна делать примерно то-то. Возможны небольшие отклонения от идеального решения, ибо идеальное решение будет работать дольше жизни вселенной.

WH>>При этом нужно уложится в 50 миллисекунд. А лучше в 10.
__>вот меня кстати удивляет когда люди пишут такие задачи без юнит тестов, по крайней мере на сам алгоритм.
Ну так ты расскажи как?
Точное решение не подходит, ибо неприемлемо долго.
Иногда даже нельзя чётко сформулировать что значит точное решение.
Те до того, как задача решена невозможно даже сказать, что должно быть на выходе.
Те ты даже функциональный тест на всю задачу написать не сможешь.
А юнит тесты тоже писать невозможно, ибо детали реализации алгоритма могут изменятся до неузнаваемости по 10 раз в месяц.
Обычное дело: сегодня написал функцию, а завтра удалил. Ну и зачем писать тест, на код, который прожил сутки?

WH>>Имей в виду что при решении таких задач весь код несколько раз переписывается.

__>вы мне просто мою работу описываете.
Больше похоже на то что я разговариваю с человеком, который всю жизнь переливал данные из БД в ГУИ и обратно, но очень хочет выглядеть крутым.

__>если кто-то придет и скажет "я пеерписал весь код, теперь он работает правильно и быстро", я скажу — "докажи!".

Доказать? Тестами?
Тесты ловят только регрессии.
Причем регрессии не всегда являются ошибками.

WH>>Запускать все тесты на каждый коммит весьма странная затея.

WH>>Полностью тестировать нужно только перед отправкой кода в главную ветку. А рабочие ветки могут даже не компилироваться. И ничего плохого в этом нет.
__>и отправда в главную ветку это целое эпохальное событие с неожиданной развязкой? батюшку приглашаете для освящения сервера, дабы повысить шансы, что ничего не сломается? никаких других вариантов пока не придумали?
Да ты ещё и читать не умеешь? Как же ты программы то пишешь?
Может отсюда и пошла страсть к мелким функциям.
... << RSDN@Home 1.2.0 alpha 5 rev. 62>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[13]: Функции должны быть компактными
От: __kot2  
Дата: 27.04.16 13:49
Оценка:
Здравствуйте, WolfHound, Вы писали:
WH>А юнит тесты тоже писать невозможно, ибо детали реализации алгоритма могут изменятся до неузнаваемости по 10 раз в месяц.
то есть вы пишите код и обьявляете его правильным? "силой, данной мне универом, обьявляю этот код корректным?"
или проводите какое-то тестирование? какое? ручное? а когда что-то меняете? снова проводите ручное тестирование? своего времени не жалко?

WH>Обычное дело: сегодня написал функцию, а завтра удалил. Ну и зачем писать тест, на код, который прожил сутки?

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

WH>>>Имей в виду что при решении таких задач весь код несколько раз переписывается.

__>>вы мне просто мою работу описываете.
WH>Больше похоже на то что я разговариваю с человеком, который всю жизнь переливал данные из БД в ГУИ и обратно, но очень хочет выглядеть крутым.
я очень удивлен, что очевидные вещи, которые я тут говорю, встречаются с огнем и вилами. если вы давно выпали из современной разработки, предлагаю начать потихоньку впадать обратно и начать хотя бы с чтения writing secure code — кстати, уже достаточно старого баяна.

WH>Доказать? Тестами?

WH>Тесты ловят только регрессии.
WH>Причем регрессии не всегда являются ошибками.
думаете, в коде IT нет багов? да миллион. просто они на его тестах или не проявляются или он их пропускает. и как, интересно, он думает поступать в случае, когда проектом станут пользоваться толпы людей и повалятся тысячи багрепортов? начать веерные правки?

WH>Да ты ещё и читать не умеешь? Как же ты программы то пишешь?

ладно, похоже, тема переходит в бисерометание, по крайней мере с моей стороны, поэтому закругляюсь, чтобы больше не раздражжать людей. я свою мысль по-моему достаточно четко выразил
Re[2]: Функции должны быть компактными
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 27.04.16 13:52
Оценка:
Здравствуйте, __kot2, Вы писали:

__>любой человек, который до сих пор пишет ф-ии в столбик строк по 30, вставляя туда комменты просто неквалифицирован и его нельзя допускать до написания реального кода


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

Например в VS удобно просмотреть код метода по месту вызова, а вот например в 1С такой возможности нет.
и солнце б утром не вставало, когда бы не было меня
Отредактировано 27.04.2016 13:54 Serginio1 . Предыдущая версия .
Re[10]: Функции должны быть компактными
От: IT Россия linq2db.com
Дата: 27.04.16 14:11
Оценка:
Здравствуйте, __kot2, Вы писали:

__>то есть стандартный класс нам диктует как писать код?

__>если ваша абстракция не полностью соотв-ет стандартному классу, то все, ничего нельзя поделать?

При чём тут моя абстракция?
Есть пример кода, который использует стандартный класс, который нельзя расширять. Нужно этот код переписать в 10 строк. Продемонстрируй мастер класс.
Если нам не помогут, то мы тоже никого не пощадим.
Re[10]: Функции должны быть компактными
От: MozgC США http://nightcoder.livejournal.com
Дата: 27.04.16 14:27
Оценка:
Здравствуйте, __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-х")?
Отредактировано 27.04.2016 14:56 MozgC . Предыдущая версия . Еще …
Отредактировано 27.04.2016 14:35 MozgC . Предыдущая версия .
Re[11]: Функции должны быть компактными
От: __kot2  
Дата: 27.04.16 15:00
Оценка:
Здравствуйте, IT, Вы писали:
IT>При чём тут моя абстракция?
IT>Есть пример кода, который использует стандартный класс, который нельзя расширять. Нужно этот код переписать в 10 строк. Продемонстрируй мастер класс.
откуда такое странное нельзя? кто запрещает-то? это незаконно, чтоли?
я сначала пишу код так, как если бы я выразил его словами

то есть вообще-то это обход дерева — tree_traversal
или в раскрытом виде — лямбда на ноде и рекурсивно вызов для дочерних нодов.
это и называется — ф-ия делает одну вещь. она обходит дерево. все остальное не относится к обходу дерева и не должно быть в этой ф-ии, чего бы мы с деревом не делали. и она не должна называться visit, transform или там do, чтобы не занимапться гаданиями на тему что же там реально внутри проихсодит

потом уже когда становятся понятны используемые абстракции, можно их описать, часто даже переиспользуя стандартные. в C# есть стандартные достаточно параметризуемые алгоритмы работы с деревьями? если да, то зачем нам вообще писать свой traversal? нельзя ли написать что-то в духе Tree<>::in_order_traversal(expression, f) ? вам что, правда нужно заглянуть внутрь этого метода, чтобы узнать как он реализован? вы не знаете, что такое in order tree traversal?
Re: Функции должны быть компактными
От: AndrewN Россия  
Дата: 27.04.16 15:11
Оценка: 9 (1) +2
Здравствуйте, dosik, Вы писали:

D>В своей книге Р. Мартин утверждает, что функции необходимо предъявлять всего два требования:

D>1. они должны быть компактными
D>2. они должны быть еще более компактными
D>Т.е. функция должна выполнять лишь одну операцию. Функции, выполняющие несколько операций необходимо дробить на несколько.
D>Тогда вопрос: А как же накладные расходы на вызов функции? Ведь вместо того, чтобы продолжить вычисления, теперь нам надо заполнить стек и передать управление по адресу, а по возвращению очистить стек. Т.е. улучшая читабельность кода мы уменьшаем производительность системы. Да и как то меня учили, что в функцию необходимо выносить лишь тот код, который может быть вызван из нескольких участков программы. И какой тогда смысл выносить в отдельную функцию код, который будет вызываться только в одном месте?

Приходилось как-то ковырять исходники, в которых декомпозиция и вынесение повторяющихся кусков кода в отдельные функции было доведено до абсурда.
Почти любой фрагмент кода между if{ и } оформлялся в виде отдельной самостоятельной функции.
А в этой самостоятельной функции использовался тот же прием и так далее по рекурсии.

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

Где-то надо уметь остановиться и не доводить любую идею до абсурда.
--------------------------------------------------------------
Правильно заданный вопрос содержит в себе половину ответа
Re[14]: Функции должны быть компактными
От: WolfHound  
Дата: 27.04.16 15:12
Оценка: +1
Здравствуйте, __kot2, Вы писали:

__>то есть вы пишите код и обьявляете его правильным? "силой, данной мне универом, обьявляю этот код корректным?"

А кто поступает иначе?
Есть конечно люди, которые доказывают программы. Но их мизерное количество.

__>или проводите какое-то тестирование? какое? ручное? а когда что-то меняете? снова проводите ручное тестирование? своего времени не жалко?

А на этот случай есть регрессионные тесты.
Написал код.
Сделал несколько наборов тестовых данных.
Натравил код на каждый набор.
Записал результат в фиал.
После чего просто прогоняю тесты и сравниваю с эталоном.

Если нашёлся баг делаю новый набор данных на котором воспроизводится баг.
Чиню баг.
Генерирую эталон.
После чего стало на один тест больше.

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

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

__>я очень удивлен, что очевидные вещи, которые я тут говорю, встречаются с огнем и вилами.

Просты ты чушь порешь. А ей больно.

WH>>Доказать? Тестами?

WH>>Тесты ловят только регрессии.
WH>>Причем регрессии не всегда являются ошибками.
__>думаете, в коде IT нет багов?
Ты от вопроса не уходи.
Что ты собрался тестами доказать?
Доказывают вот так:
http://thedeemon.livejournal.com/107067.html
А тестами ловят регрессии и только регрессии.
Ибо сущность любого теста зафиксировать результат работы кода на конкретном наборе данных.
Ничего больше тесты не могут.

WH>>Да ты ещё и читать не умеешь? Как же ты программы то пишешь?

__>ладно, похоже, тема переходит в бисерометание, по крайней мере с моей стороны, поэтому закругляюсь, чтобы больше не раздражжать людей. я свою мысль по-моему достаточно четко выразил
Ты достаточно чётко слил.
... << RSDN@Home 1.2.0 alpha 5 rev. 62>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[11]: Функции должны быть компактными
От: __kot2  
Дата: 27.04.16 15:13
Оценка:
Здравствуйте, 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 ?
Re[12]: Функции должны быть компактными
От: WolfHound  
Дата: 27.04.16 15:26
Оценка:
Здравствуйте, __kot2, Вы писали:

IT>>Есть пример кода, который использует стандартный класс, который нельзя расширять. Нужно этот код переписать в 10 строк. Продемонстрируй мастер класс.

__>откуда такое странное нельзя? кто запрещает-то? это незаконно, чтоли?
__>я сначала пишу код так, как если бы я выразил его словами
Объекты этих типов генерирует компилятор C#. Для того чтобы их изменить нужно:
1)Написать компилятор C#
2)Уговорить всех пользователей Linq2DB перейти на этот компилятор.
Если первое ещё можно сделать. То второе почти не реально.

ЗЫ Linq2DB лучшая в мире реализация linq для реляционных баз данных.
... << RSDN@Home 1.2.0 alpha 5 rev. 62>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[6]: Функции должны быть компактными
От: Ikemefula Беларусь http://blogs.rsdn.org/ikemefula
Дата: 27.04.16 15:36
Оценка:
Здравствуйте, К Тёте, Вы писали:

I>>Пудозреваю, в твоих проектах это не надо делать.


КТ>Тут у всех подряд на форуме это не надо делать. Тут считанные единицы работают хоть с какой-либо нагрузкой или числодробилками.


Тут минимум в трех форумах оптимизации вызывают очень бурное обсуждение. В микроконтролерах-железе это актуально по сей день. Системное программирование — так же. Геймдев — снова числодробилки. hft, hpc, САПР — снова надо. Визуализации, аналитика всех сортов — обратно надо. Обработка изображений, звука, сигналов — адски актуально. Чуть не все хранение-обработка данных так или иначе связано с перформансом.
А вот где неактуально — обычный мейнстрим да магазины на трёх с половиной юзеров. Вот здесь как правило задачи очень мирные, но это в основном потому, что уже давно известно, что убер-алгоритмы недоступны а выжимать соки смысла нет.

I>>Например, когда вызов функции у тебя асинхронный, это само по себе дает счет на милисекунды. Что характерно, компилятор тут вообще не помощник. Если руками заинлайнить, то профит вообще сказочный.


КТ>Что заинлайнить? Куда заинлайнить?


Вызов функции. В вызывающую функцию.

I>>То есть, вне зависимости от хорошести алгоритма, потери на вызовах могут быть и 1000% и больше.


КТ>Сферовакуумные потери сферовакуумных вызовов. Да еще «вне зависимости от алгоритма». Ага, как же. Эти сказки рассказывай бабушкам на крылечке у дома.


Если у тебя обращение к элементу массива требует K приседаний, то и медленная версия, и супероптимизированая версия алгоритма, могут быть ускорены в K раз, при условии, что они зависят от длины массива N.

Собтсвенно именно отсюда и начинается разговор о производительность
1. низкоуровневые оптимизации это краткосрочная перспектива, быстрый эффект
2. улучшение алгоритмов это долгосрочная перспектива.
3. Алгоритмы меняются не просто так, а именно с учетом того самого K-на-каждую итерацию. То есть, вместо "руками пофиксим тысячу мест и получим K/10 и огребем проблемы с релизом и майнтенансом" у тебя будет алгоритм, который будет очень чувствительным именно к K и потребует низкоуровневые приседания ровно в одном месте.
4. Дело десятое, меняешь ли ты N^2 на log(N) или наоборот, главное что бы на твоём промежутке был профит. То есть, и замена быстрой на пузырек, и обратная замена могут быть, а могут и не быть оптимизациям.
Re[7]: Функции должны быть компактными
От: К Тёте  
Дата: 27.04.16 15:45
Оценка:
I>А вот где неактуально — обычный мейнстрим да магазины на трёх с половиной юзеров. Вот здесь как правило задачи очень мирные, но это в основном потому, что уже давно известно, что убер-алгоритмы недоступны а выжимать соки смысла нет.

Это неактуально и для магазинов с 10 000 пользователями и со 100 000 пользователей.


I>>>Например, когда вызов функции у тебя асинхронный, это само по себе дает счет на милисекунды. Что характерно, компилятор тут вообще не помощник. Если руками заинлайнить, то профит вообще сказочный.

КТ>>Что заинлайнить? Куда заинлайнить?

I>Вызов функции. В вызывающую функцию.


Зачем? Что это даст при асинхронном вызове? Я тебе привел пример: вызов функции — это наносекунды. У тебя латентность сети, доступ к диску и обращение к базе съедят любую придуманную твоей буйной фантазией оптимизацию от инлайнинга.

I>>>То есть, вне зависимости от хорошести алгоритма, потери на вызовах могут быть и 1000% и больше.


КТ>>Сферовакуумные потери сферовакуумных вызовов. Да еще «вне зависимости от алгоритма». Ага, как же. Эти сказки рассказывай бабушкам на крылечке у дома.


I> Если у тебя обращение к элементу массива требует K приседаний, то и медленная версия, и супероптимизированая версия алгоритма, могут быть ускорены в K раз, при условии, что они зависят от длины массива N.



Именно, фейспалм. От твоих текстов. Вызов функции в худшем варианте — 0.1 ns. Тебе расшифровать, что такое ns или сам догадаешься? Сколько должно быть вызвов этой функции, чтобы ее оптимизация до 0.04 ns дало хоть какой-то видимый прирост производительности по сравнению с заменой неоптимизированного алгоритма на оптимизированный?


I>Собтсвенно именно отсюда и начинается разговор о производительность


Нет. Разговор о производительности всегда должен начинаться с алгоритмов.
На волю, в пампасы!
Re[15]: Функции должны быть компактными
От: К Тёте  
Дата: 27.04.16 15:52
Оценка:
WH>Ибо сущность любого теста зафиксировать результат работы кода на конкретном наборе данных.
WH>Ничего больше тесты не могут.

Если нет верификатора, то (quickchek и иже с ним):
— тесты должны описывать спецификацию, а не работу кода
— тесты должны автогенерировать большой набор данных согласно спецификации
— тесты должны проверять, соответсвует ли работа кода спецификации

В итоге такие тесты выявят проблемы как в коде, так и в спецификации. Понятное дело, что даже такое не гарантирует 100% доказательство, но это лучше, чем вручную написанные тесты на ограниченном наборе данных, описывающие работу кода.
На волю, в пампасы!
Re[8]: Функции должны быть компактными
От: Ikemefula Беларусь http://blogs.rsdn.org/ikemefula
Дата: 27.04.16 16:28
Оценка: :)
Здравствуйте, К Тёте, Вы писали:

I>>Вызов функции. В вызывающую функцию.


КТ>Зачем? Что это даст при асинхронном вызове?


Милисекунды экономии. На тысяче вызовов сэкономишь секунду времени отклика приложения.

>Я тебе привел пример: вызов функции — это наносекунды. У тебя латентность сети, доступ к диску и обращение к базе съедят любую придуманную твоей буйной фантазией оптимизацию от инлайнинга.


1 Доли секунд можно не распылять, а потратить на более серьезное вычисление оптимального плана чтения с файловой системы, что в сумме сэкономит годы вагон трафика-времени-денег. Такими вещами занимется например операционная система, движок бд, серьезные серверные приложения и тд.
2 речь то про самые разные применения. Ты вот уверен, что в любом ЯП и любой VM вызов будет наносекундами меряться ?

I>> Если у тебя обращение к элементу массива требует K приседаний, то и медленная версия, и супероптимизированая версия алгоритма, могут быть ускорены в K раз, при условии, что они зависят от длины массива N.


КТ>Именно, фейспалм. От твоих текстов. Вызов функции в худшем варианте — 0.1 ns.

>Тебе расшифровать, что такое ns или сам догадаешься? Сколько должно быть вызвов этой функции, чтобы ее оптимизация до 0.04 ns дало хоть какой-то видимый прирост производительности по сравнению с заменой неоптимизированного алгоритма на оптимизированный?

Ты свою статью то открой. Как только до полиморфизма доходит, так время сразу 4.278ns
Это как раз те самые 1000% разницы. Это может выстрелить и выстреливает в задачах из списка выше. Именно потому С++ девелоперы и до сих пор востребованы на рынке. А кроме них подобными оптимизациями занимаются и в других языках.

I>>Собтсвенно именно отсюда и начинается разговор о производительность


КТ>Нет. Разговор о производительности всегда должен начинаться с алгоритмов.


О производительности — требований, далее — с замеров, показаний профайлера и достоверных сведений о проблемах. Если этого нет, то нет и оснований заводить разговор об алгоритмах.
Re[12]: Функции должны быть компактными
От: IT Россия linq2db.com
Дата: 27.04.16 17:06
Оценка:
Здравствуйте, __kot2, Вы писали:

IT>>Есть пример кода, который использует стандартный класс, который нельзя расширять. Нужно этот код переписать в 10 строк. Продемонстрируй мастер класс.

__>откуда такое странное нельзя? кто запрещает-то? это незаконно, чтоли?

Запрещает Microsoft. Это код из стандартной библиотеки.

__>я сначала пишу код так, как если бы я выразил его словами


Это твои личные проблемы. Я может тоже так делаю, но и это мои личные проблемы. Давай по существу.

__>то есть вообще-то это обход дерева — tree_traversal

__>или в раскрытом виде — лямбда на ноде и рекурсивно вызов для дочерних нодов.
__>это и называется — ф-ия делает одну вещь. она обходит дерево. все остальное не относится к обходу дерева и не должно быть в этой ф-ии, чего бы мы с деревом не делали. и она не должна называться visit, transform или там do, чтобы не занимапться гаданиями на тему что же там реально внутри проихсодит

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

В принцмпе, для самодельных деревьев я так и делаю. Но здесь ситуация не та.
Если нам не помогут, то мы тоже никого не пощадим.
Re[12]: Функции должны быть компактными
От: MozgC США http://nightcoder.livejournal.com
Дата: 27.04.16 17:09
Оценка:
Здравствуйте, __kot2, Вы писали:

__>что такое "дополнительные свойства datetime" ? я без понятия. расчет релятивистких эффектов? марсианские сутки? сериализация? форматирование? поддержка времени хищника? название ни о чем не говорит.


Имя класса DateTimeExtensions мне говорит о том, что там лежат extension methods для DateTime. Для меня это вполне достаточная гранулярность.

__>а алгоритм побуквенно переписан из древнего писания или имеет какие-то вполне разумные части, типа, расчета credit score или поправка на семейное положение? этот алгоритм можно записать текстом так, чтобы его прочитал и с первого раза понял любой человек? или там просто в столбик строчки типа

__>exptr2 += dev_thrillx(20, rack, grad_fix) * e + 8 * cutted_value/2
__>и для понимания значения их, нужно сидеть и весь день тупить в экран, ходить, выяснять, что там за phred и почему там стоит 8 ?

Это всё к чему? Куда-то мы, кажется мне, движемся в никуда...
Re[13]: Функции должны быть компактными
От: __kot2  
Дата: 27.04.16 17:16
Оценка:
Здравствуйте, IT, Вы писали:
IT>Не важно как это назвать. Важно, что тебе придётся доработать исходный класс, добавить в каждый нод по виртуальному методу. Скорее всего не по одному, т.к. кроме обхода дерева нужно ещё уметь его модифицировать, прерывать обход и т.п., т.е. сценарии обхода могут быть сильно разными.
когда мы не хотим модифицировать исходный класс у нас всегда есть минимум два варианта получить нужное — делегировать к нему или наследоваться от него
Re[13]: Функции должны быть компактными
От: __kot2  
Дата: 27.04.16 17:25
Оценка:
Здравствуйте, MozgC, Вы писали:
MC>Имя класса DateTimeExtensions мне говорит о том, что там лежат extension methods для DateTime. Для меня это вполне достаточная гранулярность.
а если я туда захочу положить код конверсии указателя солнечных часов во время и наоборот, это тоже можно extensions назвать?
со всякими хелперами и экстеншенсами проблема в том, что или можно назвать все. вот у нас есть number и есть пиксел на экране. любая программа это просто набор pixel и number extensions и helpers. весь джаваскрипт это, например, просто html extensions

вот мы взяли некие намберс, с помощью вспомогательных методов провели некие вычисления и с помощью методов расширений пикселов отобразили это на экране. логично? логично. но нифига не понятно. вот у нас есть код, который для человека расчитывает, например, прибавку к зарплате с учетом неиспользованных выходных, льгот, налогов или даже просто високосного года. я вот без понятия в каком хелпере-экстеншенсе искать подобный код — у user, у datetime (почему бы holidays не сделать расширением datetime например) у taxes (который можно сделать частью просто math? ) или снова в datetime, если разговор идет про високосный год. чаще всего вообще, когда программист понимает, что вроде как никуда оно не идет, он берет и пихает его в common). как-то в одном проекте видел common килобайт на 100
Re[14]: Функции должны быть компактными
От: IT Россия linq2db.com
Дата: 27.04.16 17:32
Оценка:
Здравствуйте, __kot2, Вы писали:

__>когда мы не хотим модифицировать исходный класс у нас всегда есть минимум два варианта получить нужное — делегировать к нему или наследоваться от него


Наследоваться не получится, т.к. не мы создаём его экземпляры. Делегировать хоть обделегируйся, но рано или поздно мы всё равно придём к тому же самому switch.
Если нам не помогут, то мы тоже никого не пощадим.
Re[15]: Функции должны быть компактными
От: __kot2  
Дата: 27.04.16 18:04
Оценка:
Здравствуйте, IT, Вы писали:
IT>Наследоваться не получится, т.к. не мы создаём его экземпляры. Делегировать хоть обделегируйся, но рано или поздно мы всё равно придём к тому же самому switch.
вообще не понимаю в чем проблема сделать UnaryExpression и BinaryExpression который будет реализовывать чисто виртуальный метод sub_expressions и выдавать соотв-но их.
или, чтобы, для перфоманса, не создавать временного списка, можно for_every_subexpression прямо соб-но его виртуальным мембером и сделать

аа, похоже понял — такие кривые экземпляры генерируются где-то внутри и нам придется перегенерировать все дерево выражений, если мы хотим работать с ним удобно. то есть основная проблема в том, что в мс придумали архитектуру с которой невыносимо работать. ну, чего ж тут удивительного. либо мы создаем дерево-враппер и работаем по-человечески, либо так криво со свичами, как говорится, в заданном стиле. хотя переименовать пару методов все равно стоит, хотя бы для того, чтобы понятно было где дерево, где его обход, а где код обработки какого рода операций
Отредактировано 27.04.2016 19:15 __kot2 . Предыдущая версия .
Re[16]: Функции должны быть компактными
От: WolfHound  
Дата: 27.04.16 18:56
Оценка:
Здравствуйте, К Тёте, Вы писали:

КТ>Если нет верификатора, то (quickchek и иже с ним):

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

КТ>В итоге такие тесты выявят проблемы как в коде, так и в спецификации. Понятное дело, что даже такое не гарантирует 100% доказательство, но это лучше, чем вручную написанные тесты на ограниченном наборе данных, описывающие работу кода.

Только где же такую спецификацию взять?
... << RSDN@Home 1.2.0 alpha 5 rev. 62>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[17]: Функции должны быть компактными
От: К Тёте  
Дата: 27.04.16 20:18
Оценка: +1 :)
WH>Спецификацию на генератор парсеров генератора парсеров.

У тебя профессиональная деформация.

КТ>>В итоге такие тесты выявят проблемы как в коде, так и в спецификации. Понятное дело, что даже такое не гарантирует 100% доказательство, но это лучше, чем вручную написанные тесты на ограниченном наборе данных, описывающие работу кода.

WH>Только где же такую спецификацию взять?

Когда нет — придумывать. Если невозможно придумать, то — увы. Но я в жизни не поверю, что весь код состоит из функций, которые невозможно описать, как они работают. Для тех, что описуемы, тесты должны покрывать описание, а не то, как код работает. Например, какой-нибудь код, который убирает дубликаты из дерева разбора. Эти деревья можно нагенерить тоннами и проверить код на бОльшем количестве вариантов, чем assert(remove_duplicates([a, b, a]) == [a, b]).
На волю, в пампасы!
Re[18]: Функции должны быть компактными
От: __kot2  
Дата: 27.04.16 20:42
Оценка:
Здравствуйте, К Тёте, Вы писали:
КТ>Когда нет — придумывать. Если невозможно придумать, то — увы. Но я в жизни не поверю, что весь код состоит из функций, которые невозможно описать, как они работают. Для тех, что описуемы, тесты должны покрывать описание, а не то, как код работает. Например, какой-нибудь код, который убирает дубликаты из дерева разбора. Эти деревья можно нагенерить тоннами и проверить код на бОльшем количестве вариантов, чем assert(remove_duplicates([a, b, a]) == [a, b]).
в алгоритмах есть можно сказать "точки разрыва" — когда поведение меняется. то есть есть ф-ия, например, которая число печатает. переход от одной цифры к двум — такая "тока разрыва непрерывности решения". да, мы можем нагенерировать тонну, там, списков для проверки правильно работы убирания дубликатов, но разумнее специфицировать это примерно так:

[] -> [] // это спецификация на "невалидные данные"
[a] -> [a] // на данные, которые не нужно обрабатывать
[a, a] -> [a] // простейший пример
[a, a, a] -> [a] // а то вдруг там иф будет стоять, который пару схлопнет, а тройку нет
[a, b, a] -> [a, b] // дубликат, стоящий неподряд
[b, a, b, a] -> [b, a] // два дубликата неподряд
[a, b, c, b] -> [a, b, c] // убираем не первую букву (а то в остальных тестах она у нас че-то первая стоит)

минимальный код, который будет проходить эти тесты, должен будет убирать дубликаты по-нормальному

кстати, тест [b, a, b, a] -> [b, a] требует не просто убирания дубликатов, а сохранения их исходного порядка. что дает повод нам задуматься — а надо ли оно нам? мы-то знаем, что проще всего реализовать без сохранения порядка. вот почему мы вдруг от задачи "убрать дубликаты" вдруг перешли к вопросу "а сохранить ли порядок" и выяснили это не потом, когда что-то упало и мы в дебагере нашли, что порядок изменился и такие, Васе говорим "а че ты порядок-то поменял, олень? а он такой — "ды ну ты ж сам сказал, что дубликаты убрать надо, я и убрал, про порядок никто ниче не говорил"".
Отредактировано 27.04.2016 20:48 __kot2 . Предыдущая версия .
Re[16]: Функции должны быть компактными
От: IT Россия linq2db.com
Дата: 27.04.16 20:43
Оценка: +2
Здравствуйте, __kot2, Вы писали:

__>аа, похоже понял — такие кривые экземпляры генерируются где-то внутри и нам придется перегенерировать все дерево выражений,


Ты не архитектуру критикуй, а перепиши этот switch в 10 строк. Критиковать, особенно MS дело не хитрое. Мы все тут мега архитекторы даже не через одного, а по два раза каждый. Давай код.
Если нам не помогут, то мы тоже никого не пощадим.
Re[17]: Функции должны быть компактными
От: __kot2  
Дата: 27.04.16 20:51
Оценка: :)))
Здравствуйте, IT, Вы писали:
IT>Ты не архитектуру критикуй, а перепиши этот switch в 10 строк. Критиковать, особенно MS дело не хитрое. Мы все тут мега архитекторы даже не через одного, а по два раза каждый. Давай код.
это сильно искусственный пример. предлагаешь поменять архитектуру с условием неизменности каких-то частей.
да, иногда есть причины написать говенный код, это одна из них — архитектура определена другим. но это не делает код на свичах менее гавенным. это просто его оправдывает. типа, у меня сломалась машину в лесу, я воткнул палку в двигатель, так и езжу.
Re[18]: Функции должны быть компактными
От: WolfHound  
Дата: 27.04.16 20:58
Оценка:
Здравствуйте, К Тёте, Вы писали:

WH>>Спецификацию на генератор парсеров генератора парсеров.

КТ>У тебя профессиональная деформация.
Нет. Это просто пример задачи, на которую невозможно написать спецификацию.
Просто по тому что до того, как задача решена неясно какое решение вообще может быть.

КТ>Когда нет — придумывать. Если невозможно придумать, то — увы. Но я в жизни не поверю, что весь код состоит из функций, которые невозможно описать, как они работают.

Ну так покажи класс. Напиши спецификацию на парсер нитры.

КТ>Для тех, что описуемы, тесты должны покрывать описание, а не то, как код работает. Например, какой-нибудь код, который убирает дубликаты из дерева разбора.

У меня в дереве разбора нет дубликатов.
Ибо сама возможность появления дубликатов ведёт к цепочке комбинаторных взрывов.

КТ>Эти деревья можно нагенерить тоннами и проверить код на бОльшем количестве вариантов, чем assert(remove_duplicates([a, b, a]) == [a, b]).

Ладно, поговорим о сферокониках.
Допустим исходные деревья мы нагенерировали.
А как генерировать то с чем сравнивать?
... << RSDN@Home 1.2.0 alpha 5 rev. 62>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[18]: Функции должны быть компактными
От: IT Россия linq2db.com
Дата: 27.04.16 22:52
Оценка: +1 :))
Здравствуйте, __kot2, Вы писали:

__>это сильно искусственный пример. предлагаешь поменять архитектуру с условием неизменности каких-то частей.


Это рабочий код. Всё, что тебе нужно сделать упаковать его в 10 строк.

__>да, иногда есть причины написать говенный код, это одна из них — архитектура определена другим. но это не делает код на свичах менее гавенным. это просто его оправдывает.


Началось. Говёный код, говёная архитектура... Обычно так говорят те, у кого говёный критерий говёности как и говёные предпочтения и не только по поводу размера функций.
Если нам не помогут, то мы тоже никого не пощадим.
Re[19]: Функции должны быть компактными
От: __kot2  
Дата: 27.04.16 23:12
Оценка:
Здравствуйте, IT, Вы писали:
IT>Здравствуйте, __kot2, Вы писали:
__>>это сильно искусственный пример. предлагаешь поменять архитектуру с условием неизменности каких-то частей.
IT>Это рабочий код. Всё, что тебе нужно сделать упаковать его в 10 строк.
не трогая остального кода, чтоли?
вот стоит человек, прыгает на одной ноге и пытается вилкой суп есть. я ему — ну ты бы ложку хоть взял и прыгать прекращай. а он — это у меня протез ножной заглючил, пытаюсь вот поесть приспособиться. говоришь ему сесть, тот отвечает, что ничего менять не может, хочет стоя. дурацкий способ есть? конечно же. можно ли его сделать нормальным, оставляя человека прыгать на одной ноге? нельзя.
Re[20]: Функции должны быть компактными
От: IT Россия linq2db.com
Дата: 27.04.16 23:23
Оценка:
Здравствуйте, __kot2, Вы писали:

IT>>Это рабочий код. Всё, что тебе нужно сделать упаковать его в 10 строк.

__>не трогая остального кода, чтоли?

Это жизнь, чувак (c) Есть стандартный код, который нельзя трогать. И есть задача, которую нужно решать.

__>вот стоит человек, прыгает на одной ноге и пытается вилкой суп есть. я ему — ну ты бы ложку хоть взял и прыгать прекращай. а он — это у меня протез ножной заглючил, пытаюсь вот поесть приспособиться. говоришь ему сесть, тот отвечает, что ничего менять не может, хочет стоя. дурацкий способ есть? конечно же. можно ли его сделать нормальным, оставляя человека прыгать на одной ноге? нельзя.


В аналогиях ты не силён. Это уже понятно. Код давай. Всего каких-то 10 строк.
Если нам не помогут, то мы тоже никого не пощадим.
Re[21]: Функции должны быть компактными
От: __kot2  
Дата: 28.04.16 00:41
Оценка: :)
Здравствуйте, IT, Вы писали:
IT>В аналогиях ты не силён. Это уже понятно. Код давай. Всего каких-то 10 строк.
в смысле, помочь с удалением лишних переносов строк?

я же не собираюсь разводить демагогию о компилируемости и количестве строк, мне кажется все эти разговоры о выполнении формальностей безо всякого здравого смысла это удел вахтеров
Re[19]: Функции должны быть компактными
От: К Тёте  
Дата: 28.04.16 08:49
Оценка:
КТ>>Для тех, что описуемы, тесты должны покрывать описание, а не то, как код работает. Например, какой-нибудь код, который убирает дубликаты из дерева разбора.
WH>У меня в дереве разбора нет дубликатов.
WH>Ибо сама возможность появления дубликатов ведёт к цепочке комбинаторных взрывов.

Блин. Это просто как пример был.

У вас там есть тесты на кеширование, на генерацию исключений, на рекурсию и т.п. Их вполне можно описывать.

КТ>>Эти деревья можно нагенерить тоннами и проверить код на бОльшем количестве вариантов, чем assert(remove_duplicates([a, b, a]) == [a, b]).

WH>Ладно, поговорим о сферокониках.
WH>Допустим исходные деревья мы нагенерировали.
WH>А как генерировать то с чем сравнивать?

Это — на самом деле самое сложное в написании тестов с Quickcheck'ом В случае с парсерами и генераторами вполне может вылиться в создании парсера дважды (что, естественно, лучше не делать).

Для многих функций, работающих с деревьями разбора эквивалентной моделью в тестах могут быть списки/массивы.

Грубо говоря, например есть функция, удаляющая из дерева «мертвые узлы» (на которые никто не ссылается) или те же дупликаты. Генерится дерево с мертвыми узлами для кода и из этих же элементов генерится массив для сравнения. Тестируемый код удаляет узлы из дерева, тест — из массива. Потом сравнивается наличие узлов в дереве и в массиве.

В зависимости от того, как реализована функция удаления, такой тест может быть:
— малополезен, если сама функция достаточно простая
— полезен, если функция занимается каким-то дополнительным анализом или там хитрым сравнением каких-либо свойств. Потому что тест может нагененрировать деревья произвольной сложности с гарантированным присутсвием таких вот мертвых узлов. И выявить странные пограничные случаи, которые проявляются не на remove_dead_nodes([a,b,c]), а на remove_dead_nodes([a, [b, [[c]]]]]), которые ручками в тесте никто никогда не напишет.

Повторю, что такие тесты, понятное дело:
— все равно не дают 100%-гарантию
— не всегда легко написать (скорее наоборот, нелегко, особенно если нет большого опыта в написании таких тестов, у меня, например, нет)
— не всегда можно написать
На волю, в пампасы!
Re[19]: Функции должны быть компактными
От: К Тёте  
Дата: 28.04.16 09:02
Оценка:
__>в алгоритмах есть можно сказать "точки разрыва" — когда поведение меняется. то есть есть ф-ия, например, которая число печатает. переход от одной цифры к двум — такая "тока разрыва непрерывности решения". да, мы можем нагенерировать тонну, там, списков для проверки правильно работы убирания дубликатов, но разумнее специфицировать это примерно так:

__>[] -> [] // это спецификация на "невалидные данные"

__>[a] -> [a] // на данные, которые не нужно обрабатывать
__>[a, a] -> [a] // простейший пример
__>[a, a, a] -> [a] // а то вдруг там иф будет стоять, который пару схлопнет, а тройку нет
__>[a, b, a] -> [a, b] // дубликат, стоящий неподряд
__>[b, a, b, a] -> [b, a] // два дубликата неподряд
__>[a, b, c, b] -> [a, b, c] // убираем не первую букву (а то в остальных тестах она у нас че-то первая стоит)

__>минимальный код, который будет проходить эти тесты, должен будет убирать дубликаты по-нормальному



Это все идеальная утопическая ситуация. На практике все гораздо сложнее. Ты, например, в своей «спецификации» не описал толпу вариантов, которые, в зависимости от того, насколько сложная функция уборки дупликатов, могут сработать, а могут не сработать.

Два интересных примера тут: https://youtu.be/zi0rHwfiX1Q?t=18m57s

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

Например, код сериализации для SMS-gateway'я, который вылетал на данных размером, кратных 2^8, хотя все тесты проходили. Ну, как тесты. Там был тест типа твоей «спецификации». Три строчки типа

— serialize("A") == 65
— serialize("") == -1
— deserialize(serialize("A")) == "A"
На волю, в пампасы!
Re[7]: Функции должны быть компактными
От: К Тёте  
Дата: 28.04.16 09:05
Оценка:
IT>Опять лишь штампы, догмы и наклеивания ярлыков. Демагогия, короче.

IT>Вот тебе метод на 300 строк. Иди и сделай его в 30 короче.


Ну, тут ничего не надо делать.

— Код уже разбит на функции, причем довольно мелкие
— Некоторые case'ы и функции можно сделать чуть более читаемыми, если есть pattern-matching (но в C# его нет, так что увы)
На волю, в пампасы!
Re: Функции должны быть компактными
От: Mystic Украина http://mystic2000.newmail.ru
Дата: 28.04.16 09:32
Оценка:
Здравствуйте, dosik, Вы писали:

D>Т.е. улучшая читабельность кода мы уменьшаем производительность системы.


На производительность сейчас многим наплевать. В читабельность улучшается только по мнению Мартина, который, наверное, просто не программировал на Smalltalk. Там обработка сообщений компактная донельзя, в результате при чтении чужого когда возникает проблема найти требуемую функциональность, которая где-то в проекте, но не здесь...
Re[5]: Функции должны быть компактными
От: Ikemefula Беларусь http://blogs.rsdn.org/ikemefula
Дата: 28.04.16 09:58
Оценка:
Здравствуйте, IT, Вы писали:

IT>Был у нас на одном проекте в IBM архитектор, любитель паттернов и мелких недо функций.


Я эту легенду слышал лет пятнадцать назад. Похоже, тебе тот орхетектор очень много здоровья отнял.
Re[6]: Функции должны быть компактными
От: IT Россия linq2db.com
Дата: 28.04.16 13:20
Оценка: 58 (5) +2 :))) :))) :))
Здравствуйте, Ikemefula, Вы писали:

IT>>Был у нас на одном проекте в IBM архитектор, любитель паттернов и мелких недо функций.

I>Я эту легенду слышал лет пятнадцать назад. Похоже, тебе тот орхетектор очень много здоровья отнял.

Двенадцать. Это вообще был мега проект. В плане впечатлений. Совместный проект IBM, Microsoft и Pfizer, 50+ человек одних только девелоперов, светила индустрии, понты выше крыши. Я туда шёл с трясущимися коленями и со словами "чуваки, научите меня правильно жить". Когда уходил, то у меня в жизни больше не осталось авторитетов и были окончательно разрушены все идолы, а светила низвержены с небес и рассеяны по площади щелбонами и поджопниками.

Кстати, Шариш (этот тот самый 1архитектор) со своими жалкими 77-ю классами вскоре был повержен. В соседней команде был один ещё более мега-чувак, Майкл Дрыскал (да, именно так), который решил, что 77 классов смотрятся мелковато и в похожей ситуации залудил 130 классов. Очень любил паттерны и всякие мелкие недометоды.
Если нам не помогут, то мы тоже никого не пощадим.
Re[4]: Функции должны быть компактными
От: IT Россия linq2db.com
Дата: 28.04.16 20:22
Оценка:
Здравствуйте, Privalov, Вы писали:

P>Работало быстро, но прочитать это было невозможно. В том числе, кстати, из-за имен.


Имена — ерунда. GOTO!!!
Если нам не помогут, то мы тоже никого не пощадим.
Re[5]: Функции должны быть компактными
От: Privalov  
Дата: 30.04.16 10:42
Оценка: :)
Здравствуйте, IT, Вы писали:

IT>Имена — ерунда. GOTO!!!


Нам кто-то из преподов сказал как-то, что GOTO — зло. И, программируя на Фортране 4, я везде, где только можно, использовал арифметический IF.
Re[2]: Функции должны быть компактными
От: IncremenTop  
Дата: 30.04.16 14:11
Оценка:
Здравствуйте, Pzz, Вы писали:

Pzz>Другой вопрос, что разбиение кода на мелкие функции далеко не всегда облегчает его понимание. Поэтому к этому совету надо относиться критически.


Да тут выше холивар на пустом месте. Обе стороны приводят аргументы вида крайних случаев.
Re: Функции должны быть компактными
От: Пирожочек  
Дата: 02.05.16 08:52
Оценка: 6 (1) +2
Здравствуйте, dosik, Вы писали:

Требование к разбиению кода на функции произрастает из требований читабельности. Т.е. разбиение кода на функции должно увеличивать читабельность кода, а не наоборот. Объявление функции/класса, создаёт новую абстракцию, на которую мы можем ссылаться в дальнейшем, что упрощает понимание кода. Но. Это упростит понимание, только в том случае, если абстракция переиспользуется многократно. В противном случае мы лишь повышаем сложность кода ( вместо однократного прямолинейного чтения кода нам требуется изучить абстракцию, запомнить её имя и вернуться в контекст её использования ). Как следствие, зачастую определять новую функцию имеет смысл только для устранения копи-пасты. И вот тут самое главное, различить что называется common code от coincidental code (общий код vs совпадающий код). Сommon code это код, практически всегда не завязан на контекст использования, и фактически является строительным блоком сам по себе ( для классов есть семантически близкое понятие — ADT ). Coincidental code напротив, бессмысленнен вне контекста использования, и наличие идентичного кода это всего лишь совпадение. Скорее всего при попытке вынести совпадающий код в отдельную функцию, для неё будет очень сложно придумать имя (скорее всего это будет очень специфичное имя). И что самое неприятное, вынесение coincidental code в отдельную абстракцию порождает сильное зацепление (coupling) там, где его не должно быть. Типичные примеры common code — алгоритмы. Типичные примеры coincidental code — одинаковые шаги в тест кейсах.

Немного ссылок для углубления в тему:

https://en.wikipedia.org/wiki/Abstraction_principle_(computer_programming)
https://en.wikipedia.org/wiki/Copy_and_paste_programming
http://zacharyvoase.com/2013/02/08/copypasta/
http://c2.com/cgi/wiki?CopyAndPaste
http://programmers.stackexchange.com/questions/165408/copy-and-pasted-test-code-how-bad-is-this
https://www.reddit.com/r/programming/comments/1d2mff/is_it_ok_to_split_long_functions_and_methods_into/
Re[20]: Функции должны быть компактными
От: gardener  
Дата: 05.05.16 17:54
Оценка:
__>не трогая остального кода, чтоли?
__>вот стоит человек, прыгает на одной ноге и пытается вилкой суп есть. я ему — ну ты бы ложку хоть взял и прыгать прекращай. а он — это у меня протез ножной заглючил, пытаюсь вот поесть приспособиться. говоришь ему сесть, тот отвечает, что ничего менять не может, хочет стоя. дурацкий способ есть? конечно же. можно ли его сделать нормальным, оставляя человека прыгать на одной ноге? нельзя.

Т.е. ты сова стратег из анекдота?

Жили-были мыши. Все их обижали. Однажды пришли мыши к сове:
-Мудрая сова, помоги! Все нас едят. Скоро нас не останется. Что делать ?
Подумала сова и говорит:
-Мыши! Станьте ежами! Будете колючими и для охотников недоступны.
Побежали мыши радостно:
-Станем ежами! Станем ежами!
Вдруг одна остановилась:
-А кто-нибудь знает: как стать ежами?
Никто. Побежали обратно к сове.
-Сова! А как нам стать ежами???
-Мыши! Идите на хуй! Я не тактик, я — стратег !
Re[7]: Функции должны быть компактными
От: landerhigh Пират  
Дата: 17.05.16 10:19
Оценка:
Здравствуйте, IT, Вы писали:

IT>Опять лишь штампы, догмы и наклеивания ярлыков. Демагогия, короче.

IT>Вот тебе метод на 300 строк. Иди и сделай его в 30 короче.

На плюсах — запросто. Главное, чтобы потом коллеги за шаблонное колдунство не побили

А вообще подобные огромные switch..case зачастую являются гнездом багов. Особенно на языках, бедных средствами статического анализа и автоматического рефакторинга. В отсутствие тестов баги могут оставаться незамеченными годами.
www.blinnov.com
Re[11]: Функции должны быть компактными
От: landerhigh Пират  
Дата: 17.05.16 10:28
Оценка: +1 :)
Здравствуйте, WolfHound, Вы писали:

WH>А вот скажи мне как писать тесты до кода если задача ставится так:

WH>Сделай хрень, которая должна делать примерно то-то. Возможны небольшие отклонения от идеального решения, ибо идеальное решение будет работать дольше жизни вселенной.
WH>При этом нужно уложится в 50 миллисекунд. А лучше в 10.

Элементарно. Наливаем кофе. Чтим кывт. Смотрим трубку. Решаем немного поработать. Дробим задачу на подхрени. IDE не открываем! Потом каждую подхрень дробим на еще более мелкие подхрени. Повторяем, пока не наступает просветление. И только потом открываем IDE и начинаем реализовыать подхрени, выбрав самую маленькую для начала. Покрываем юнит-тестами. По пути наступает еще пара эпизодов просветления.

WH>Имей в виду что при решении таких задач весь код несколько раз переписывается.


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

WH>Запускать все тесты на каждый коммит весьма странная затея.


Ага, тесты должны выполняться при каждой сборке. Еще до коммита.
www.blinnov.com
Re[8]: Функции должны быть компактными
От: IT Россия linq2db.com
Дата: 17.05.16 16:58
Оценка:
Здравствуйте, landerhigh, Вы писали:

IT>>Вот тебе метод на 300 строк. Иди и сделай его в 30 короче.

L>На плюсах — запросто. Главное, чтобы потом коллеги за шаблонное колдунство не побили

Ну так давай. Зачем дело встало?
Если нам не помогут, то мы тоже никого не пощадим.
Re[9]: Функции должны быть компактными
От: landerhigh Пират  
Дата: 17.05.16 18:22
Оценка:
Здравствуйте, IT, Вы писали:

L>>На плюсах — запросто. Главное, чтобы потом коллеги за шаблонное колдунство не побили

IT>Ну так давай. Зачем дело встало?

За инвестором, как обычно.
www.blinnov.com
Re[10]: Функции должны быть компактными
От: IT Россия linq2db.com
Дата: 18.05.16 14:00
Оценка:
Здравствуйте, landerhigh, Вы писали:

IT>>Ну так давай. Зачем дело встало?

L>За инвестором, как обычно.

Жаль. Я чуть было тебе не поверил.
Если нам не помогут, то мы тоже никого не пощадим.
Re[11]: Функции должны быть компактными
От: landerhigh Пират  
Дата: 18.05.16 14:13
Оценка:
Здравствуйте, IT, Вы писали:

IT>>>Ну так давай. Зачем дело встало?

L>>За инвестором, как обычно.
IT>Жаль. Я чуть было тебе не поверил.

То есть инвестора нет? Жаль, но свободного времени у меня тоже.
www.blinnov.com
Re[12]: Функции должны быть компактными
От: IT Россия linq2db.com
Дата: 18.05.16 15:20
Оценка:
Здравствуйте, landerhigh, Вы писали:

IT>>Жаль. Я чуть было тебе не поверил.

L>То есть инвестора нет? Жаль, но свободного времени у меня тоже.

Т.е. просто так языком потрепать время всегда есть, а поотвечать за свои слова — нет. Всё как обычно
Если нам не помогут, то мы тоже никого не пощадим.
Re[13]: Функции должны быть компактными
От: landerhigh Пират  
Дата: 18.05.16 15:26
Оценка:
Здравствуйте, IT, Вы писали:

L>>То есть инвестора нет? Жаль, но свободного времени у меня тоже.

IT>Т.е. просто так языком потрепать время всегда есть, а поотвечать за свои слова — нет. Всё как обычно

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

Но доказывать что-то кому-то ценой своего несвободного времени, когда я могу его потратить с заметной отдачей? Зачем?
www.blinnov.com
Re[14]: Функции должны быть компактными
От: IT Россия linq2db.com
Дата: 18.05.16 15:45
Оценка:
Здравствуйте, landerhigh, Вы писали:

L>На слабо меня брать бесполезно.


Да кому ты нужен?

L>Совершенно верно, время пофлудить при ожидании компиляции есть. Точнее, отметить, что километровые switch..case являются рассадником багов и плохо поддерживаются.


Такие пустопорожние ответы здесь мало кого интересуют. Покажи код, тогда поговорим.

L>Но доказывать что-то кому-то ценой своего несвободного времени, когда я могу его потратить с заметной отдачей? Зачем?


У людей, любящих только потрепать языком есть два стандартных ответа: "это секретная информация" и "у меня нет на это времени". Впрочем, признаю, ты внёс в это небольшое разнообразие, предлагая оппоненту заплатить ему за доказательство тобой твоей собственной точки зрения.
Если нам не помогут, то мы тоже никого не пощадим.
Re[15]: Функции должны быть компактными
От: landerhigh Пират  
Дата: 18.05.16 15:53
Оценка: :)
Здравствуйте, IT, Вы писали:

L>>На слабо меня брать бесполезно.

IT>Да кому ты нужен?

Слив защитан.

L>>Совершенно верно, время пофлудить при ожидании компиляции есть. Точнее, отметить, что километровые switch..case являются рассадником багов и плохо поддерживаются.

IT>Такие пустопорожние ответы здесь мало кого интересуют. Покажи код, тогда поговорим.

Код чего?

L>>Но доказывать что-то кому-то ценой своего несвободного времени, когда я могу его потратить с заметной отдачей? Зачем?

IT>У людей, любящих только потрепать языком есть два стандартных ответа: "это секретная информация" и "у меня нет на это времени". Впрочем, признаю, ты внёс в это небольшое разнообразие, предлагая оппоненту заплатить ему за доказательство тобой твоей собственной точки зрения.

Я заявил две вещи. Первое, что на плюсах подобные длинные switch..case зачастую можно вообще убрать с помощью шаблонной магии (все подобное делали), а второе — что поддерживать такую колбасу очень сложно, внести баг, который никак себя не будет проявлять годами проще пареной репы. С чем ты не согласен?
www.blinnov.com
Re[16]: Функции должны быть компактными
От: IT Россия linq2db.com
Дата: 18.05.16 16:04
Оценка:
Здравствуйте, landerhigh, Вы писали:

L>Слив защитан.


Дружище, я вижу ты ещё и большой специалист по сливам

L>Я заявил две вещи. Первое, что на плюсах подобные длинные switch..case зачастую можно вообще убрать с помощью шаблонной магии (все подобное делали), а второе — что поддерживать такую колбасу очень сложно, внести баг, который никак себя не будет проявлять годами проще пареной репы. С чем ты не согласен?


Твои заявления мало интересны. Покажи код как ты "с помощью шаблонной магии" и всё такое. Просто слов мы тут уже достаточно наслушались и сами наговорили. Давай код.
Если нам не помогут, то мы тоже никого не пощадим.
Re[17]: Функции должны быть компактными
От: landerhigh Пират  
Дата: 18.05.16 16:07
Оценка:
Здравствуйте, IT, Вы писали:

L>>Я заявил две вещи. Первое, что на плюсах подобные длинные switch..case зачастую можно вообще убрать с помощью шаблонной магии (все подобное делали), а второе — что поддерживать такую колбасу очень сложно, внести баг, который никак себя не будет проявлять годами проще пареной репы. С чем ты не согласен?

IT>Твои заявления мало интересны. Покажи код как ты "с помощью шаблонной магии" и всё такое. Просто слов мы тут уже достаточно наслушались и сами наговорили. Давай код.

А если покажу? Примера под рукой нет, надо поискать или набросать.
www.blinnov.com
Re[7]: Функции должны быть компактными
От: AUDev  
Дата: 06.06.16 13:06
Оценка:
Здравствуйте, IT, Вы писали:

IT>Вот тебе метод на 300 строк. Иди и сделай его в 30 короче.


Не в тему холивара о длине функций, но пришлось не так давно, и уже не первый раз, писать подобное для JavaScript. Свой код не буду приводить (там еще производятся действия, которые будут отвлекать от сути), но например вот 15 строк кода который траверсит весь AST JavaScript-а. Идея в обходе всех объектных свойств вместо хардкода путей обхода, структура этого AST это позволяет. Твой метод Visit читал не досконально, но теоретически ведь можно в твоем случае без хардкода структуры обхода просто делать перебор свойств типа Expression (или типа коллекции/массива Expression) у переданного в Visit объекта, и вызывать Visit для значений этих свойств (или свойств элементов коллекции Expression), если порядок обхода свойств не важен?
Отредактировано 06.06.2016 13:14 AUDev . Предыдущая версия .
Re[8]: Функции должны быть компактными
От: IT Россия linq2db.com
Дата: 06.06.16 13:48
Оценка: +1
Здравствуйте, AUDev, Вы писали:

AUD>но теоретически ведь можно в твоем случае без хардкода структуры обхода просто делать перебор свойств типа Expression (или типа коллекции/массива Expression) у переданного в Visit объекта, и вызывать Visit для значений этих свойств (или свойств элементов коллекции Expression), если порядок обхода свойств не важен?


Если бы и можно было, то я бы не стал этого делать из соображений производительности.

Но нельзя минимум по двум причинам.
Во-первых, эта структура не однородная. Т.е. в ней встречаются объекты как здесь, которые имеют другой тип, но в них есть наш Expression. Т.е. происходит определённый разрыв.
Во-вторых, в члучае трансформаций для Expression вызывается метод Update специфичный для конкретного типа Expression.
Если нам не помогут, то мы тоже никого не пощадим.
Re[2]: Функции должны быть компактными
От: 0BD11A0D  
Дата: 07.06.16 12:56
Оценка:
Здравствуйте, Пирожочек, Вы писали:

П>Но. Это упростит понимание, только в том случае, если абстракция переиспользуется многократно.


Не согласен.

Если переиспользуется, то экстрагировать надо по соображениям нормализации (грубо говоря, чтобы в дальнейшем править один раз, а не по списку).

А упростить понимание функция может и при однократном использовании — если она соответствует тому, что типичный человек в алгоритме написал бы словами. То есть, Смешать(), Посыпать() и Помазать() это хорошие функции, даже если все это надо сделать только один раз.
Re[3]: Функции должны быть компактными
От: chaotic-kotik  
Дата: 10.06.16 10:55
Оценка:
D>>А что тогда с высоконагруженными приложениями, где кроме как на себя, даже на компилятор положиться нельзя?
N>А что такое "высоконагруженые приложения", пример можно? Или вы чисто теоретически интересуетесь?

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