"накладные расходы" при работе программы

Общие принципы, проектирование, модуляризация, темплейты и шаблоны

"накладные расходы" при работе программы

Postby Artem.spb on 02 Aug 2018, 12:46

Работа над очередным проектом и дискуссии с IvanLis сподвигли на небольшое тестирование.
Но сначала немного воды.
По моему субъективному мнению программисты делятся на 10 категории.
1 программируют на :labview:
10 программируют на С.

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

С другой стороны, мне "повезло" начинать с :labview:, но вот с классами я до сих пор толком не подружился. Уже года три их использую, но в качестве удобной обёртки на кластеры, чтобы не загромождать ПУ. Ведь чем дальше и больше проекты, тем больше переменных приходится хранить. И тем больше разрастаются typedef-ы. Но порой возникает вопрос «а надо ли»? Сколько «стоит» мне каждый класс, а точнее, его вызов. И вот, наконец, руки дошли до проверки.
Итак, к делу. Что проверяем: сколько времени тратит система на вызов конкретной функции. Для чистоты эксперимента данные должны меняться, иначе оптимизатор наоптимизирует и ничего вызывать не будет. С другой стороны, сама функция должна работать минимальное время, иначе сложно будет отделить мух от котлет. Поэтому выбирают обычный инкремент.
Дальше, данные обычно запрятаны в кластеры, размер которого «а фиг его знает», потомучто могут быть и массивы и строки и т.п. Поэтому «рабочую» переменную прячу между двух элементов «неопределённой» длины.
Список вариантов работы
1. провода. Самое первое и простое. Сколько «стоит» гонять данные по регистрам.
2. кластер. Появляются при усложнении программ. во что обойдётся разобрать/собрать для изменение одного элемента.
3. in place. Аналогично. Предполагается, что этот метод будет быстрее предыдущего.
4. просто функция. Появляется, когда БД уже не влезает на экран.
5. просто функция с in place. Аналогично с 2-3, но с обёрткой в виде простой функции.
6. статический класс. То же самое, что 4, но в виде класса.
7. статический класс с in place. То же самое, что 5, но в виде того же класса.
8. динамический класс. = 6, но с возможностью override
9. динамический класс-наследник с вызовом родителя. Тут непонятно, что тестирую , но т..к прямого доступа к данным родителя нет, проверю такой способ.
10. динамический класс-наследник. В классе появляется новая переменная. Её и увеличиваю.
11. динамический класс-наследник с доступом к данным. У родителя появляются функции get/set. С их помощью и увеличиваю исходную переменную.

Весь код рисовать тут не буду, в принципе функции примерно так выглядят.
cluster.png
cluster.png (11.89 KiB) Viewed 796 times

А это весь тестер.
main.png


Для пущей достоверности (и чтобы не выключать везде отладку руками) делаю ехе.
Теперь результаты.
results.PNG


Ожидаемо провода оказались самыми быстрыми.
Разбор кластера неизбежно тянет расходы. Тоже в принципе ожидаемо. Неожиданно in place тратит на работу с кластером больше времени.
inplace.PNG
inplace.PNG (6.58 KiB) Viewed 796 times


вызов функции «стоит» 10^-5c. В 20-30 раз дольше, чем просто кластеры, но параноиком быть не надо, это не повод создавать спагетти-диаграммы. in place и тут подводит… Проверял на массивах длиной 500 и 1 000 000 элементов, цифры схождие, так что объёмы передаваемых данных не влияют на скорость вызова функции.
Дальше самое интересное. Стоит функции стать классом, как она замедляется процентов на 20-30. А in place наконец-то обгоняет unbandle.
Но стоит функции стать динамической, как скорость вызова падает в три раза.
Особо интересно выглядят 9 и 11. «поиск» родителя и его вызов вполне объясняют такой рост времени вызова. Но что странно: вызов внутри функции ещё двух функций родительского класса не замедляет работу, даже наоборот. 8 (изменение переменной в «надстройке») работает чуть дольше, чем 11 (изменение переменной родителя). Впрочем, объяснение скорости нашёл, data member access работают через inline.

выводы: не всё так страшно. Если функция выполняет существенную работу, то затраты на её вызов позволительная роскошь в угоду удобству программирования/отладки.
С другой стороны, если важна скорость работы, то совсем мельчить не стоит, много ресурсов будет тратиться на вызовы, а не полезную работу, что и так было известно, просто в очереднйо раз подтверждаем этот факт.
Ну а классы… пора их осваивать серъёзно :)

Ну и самое непонятное в этом тесте: почему массивы уползают со своего места после билдера.…
vi.PNG
vi.PNG (7.73 KiB) Viewed 796 times
exe.PNG
exe.PNG (7.67 KiB) Viewed 796 times


Тестировал на LV16. Для желающих погонять прикладываю и 12
комменты и предложения ожидаются.
Attachments
speed_compare.zip
исходники 16
(197.78 KiB) Downloaded 14 times
12.zip
исходники 12
(139.36 KiB) Downloaded 12 times
Artem.spb
expert
expert
 
Posts: 1399
Joined: 31 Jul 2011, 23:05
Medals: 2
Activity (1) Автор (1)
LabVIEW Version: 12,14,15
Karma: 239
CLD hardware I/O VIP freelance

Re: "накладные расходы" при работе программы

Postby Artem.spb on 03 Aug 2018, 09:49

Небольшое дополнение в пользу классов, вспомнил что не так давно проверял, стоит ли злоупотреблять вызовами по ссылке.
Редко, но случается так, что до исполнения кода не известно, какая функция понадобится. или надо добавить универсальности, чтобы можно было менять исполняемую функцию "на ходу".
В простых случаях вопрос решается кейсами. В более сложных вариантах можно использовать call by ref с подменой исполняемой функции. Ну и само собой возникает вопрос скорости. Откопал свой старый тест. Сначала функцию вызываю как subVI, потом два раза по ссылке. Функция «a+b» опять же для чистоты эксперимента.
Время исполнения различается на порядок (практически точно 10 раз), результат стабильный при нескольких повторах теста.
Вспоминаем «динамические» классы. Там падение скорости примерно раз в 5. Итого, классы в таких ситуациях использовать выгоднее.

refVSsubVI.PNG
refVSsubVI.PNG (5.07 KiB) Viewed 767 times
Artem.spb
expert
expert
 
Posts: 1399
Joined: 31 Jul 2011, 23:05
Medals: 2
Activity (1) Автор (1)
LabVIEW Version: 12,14,15
Karma: 239
CLD hardware I/O VIP freelance

Re: "накладные расходы" при работе программы

Postby IvanLis on 14 Aug 2018, 13:32

По поводу In Place Element Structure была тема: viewtopic.php?f=87&t=3404
Но было это давно и судя по выводам, с ростом версии LV выигрыш должен стать более существенным.
User avatar
IvanLis
professor
professor
 
Posts: 4628
Joined: 02 Dec 2009, 17:44
Location: СССР
Medals: 7
Activity (2) Professionalism (1) Tutorials (1) Gold (1) Man of the year 2012 (1)
Автор (1)
LabVIEW Version: 2010
Karma: 727
hardware VIP bloggers teachers

Re: "накладные расходы" при работе программы

Postby Kosist on 14 Aug 2018, 15:41

Artem.spb wrote:Уже года три их использую, но в качестве удобной обёртки на кластеры, чтобы не загромождать ПУ. Ведь чем дальше и больше проекты, тем больше переменных приходится хранить. И тем больше разрастаются typedef-ы.

А вот это Вы зря... В качестве обертки нужно subVI тогда использовать, меньше вреда будет... Ибо это - в корне неправильное использование классов. Ведь классы нужны для ООП, а заменяя кластеры на классы - Вы не получаете ООП, Вы все так же следуете процедурному подходу.
Это для меня немного "больная тема", т.к. приходиться поддерживать код, в котором используется один класс, внутри него - мега кластер, и вокруг него - куча методов. А создатель сего творения был уверен, что он сделал приложение в ООП стиле. Ага...
Ведь вместо того, чтобы, например, увеличивать к-ство элементов в кластере -> нужно создать правильную иерархию классов, и "наращивать" количество данных вглубь иерархии, а не раздувать количество данных в родительском классе. И т.д., и т.п.
Переход на ООП всегда болезнен, но если не пытаться, то ничего не выйдет... А просто пряча функции и данные за классами, код больше проигрывает, чем получает - особенно если его будет поддерживать человек, который привык использовать классы правильно.
Artem.spb wrote:Редко, но случается так, что до исполнения кода не известно, какая функция понадобится. или надо добавить универсальности, чтобы можно было менять исполняемую функцию "на ходу".

А по этому поводу очень интерестная тема есть в LabVIEW примерах версии >= 2016. C:\Program Files (x86)\National Instruments\LabVIEW xxxx\examples\Channels\Replacing The Function At The Heart Of An Algorithm At Run Time -> там есть серия примеров, как заменять функции "на лету", плюсы и минусы, и т.д. Интерестно, и жаль что так спрятано в примерах - ведь многие об этих подходах и не догадываются, или не считают нужным использовать...
Мы делили апельсин - много наших полегло...
User avatar
Kosist
leader
leader
 
Posts: 877
Joined: 21 Feb 2011, 23:44
Medals: 2
Activity (1) Gold (1)
LabVIEW Version: 2013-2017
Karma: 246
CLAD I/O VIP students

Re: "накладные расходы" при работе программы

Postby Artem.spb on 14 Aug 2018, 17:09

Kosist wrote: А просто пряча функции и данные за классами, код больше проигрывает, чем получает - особенно если его будет поддерживать человек, который привык использовать классы правильно.

как говорится, пруфлинк в студию.
в чём проигрывает код?
то, что человек проигрывает - вопрос субъективный. Я вот почти все коды критикую "да кто ж так программирует?". Я даже свои старые исходники открываю: "это что, я кодил???"

А по этому поводу очень интерестная тема есть в LabVIEW примерах версии >= 2016

пример давно уже изучал, красиво сделано.
Artem.spb
expert
expert
 
Posts: 1399
Joined: 31 Jul 2011, 23:05
Medals: 2
Activity (1) Автор (1)
LabVIEW Version: 12,14,15
Karma: 239
CLD hardware I/O VIP freelance

Re: "накладные расходы" при работе программы

Postby Artem.spb on 14 Aug 2018, 17:19

Kosist wrote:Ведь вместо того, чтобы, например, увеличивать к-ство элементов в кластере -> нужно создать правильную иерархию классов, и "наращивать" количество данных вглубь иерархии, а не раздувать количество данных в родительском классе. И т.д., и т.п.

раз пошла такая пьянка, дайте "совет старшего брата". Тут у меня как раз затык. Начинаю разбиваnь данные на классы и...
для примера
класс 1 = класс 2 + класс 3 + класс 4
класс 4 = класс 5 + класс 6
И в программе я работаю с классом 1.
нужно вызвать метод класса 6.

Варианта два в моей голове.
1) класс 1 имеет метод, вызывающий метод "4", который вызывает "6"
итого, на вызов одной функции я пишу 3 :crazy:

2) то, что в текстах выглядит "красиво" класс1.класс4.класс6.нужныйМетод
только в :labview: это не столь элегантно и опять же надо вызвать последовательно 4 функции (три из которых - data member access)
Artem.spb
expert
expert
 
Posts: 1399
Joined: 31 Jul 2011, 23:05
Medals: 2
Activity (1) Автор (1)
LabVIEW Version: 12,14,15
Karma: 239
CLD hardware I/O VIP freelance

Re: "накладные расходы" при работе программы

Postby Kosist on 14 Aug 2018, 18:17

Artem.spb wrote:как говорится, пруфлинк в студию.
в чём проигрывает код?
то, что человек проигрывает - вопрос субъективный. Я вот почти все коды критикую "да кто ж так программирует?". Я даже свои старые исходники открываю: "это что, я кодил???"

Это как на игровом топовом компьютере смотреть только видео в ютюбе. Как бы можно, все работает - но мощные ресурсы не используются, и тогда вопрос, нужны ли такие ресурсы вообще?
Код не проигрывает в производительности, но в целом это как бы перебор, overkill. Т.е. мощный подход, а используется для простых целей. Это как иметь Ферарри, и ездить по городу 40 км в час, ни разу не выжав газ в пол за городом ))))

Artem.spb wrote:раз пошла такая пьянка, дайте "совет старшего брата". Тут у меня как раз затык. Начинаю разбиваnь данные на классы и...
для примера
класс 1 = класс 2 + класс 3 + класс 4
класс 4 = класс 5 + класс 6
И в программе я работаю с классом 1.
нужно вызвать метод класса 6.

Варианта два в моей голове.
1) класс 1 имеет метод, вызывающий метод "4", который вызывает "6"
итого, на вызов одной функции я пишу 3 :crazy:

2) то, что в текстах выглядит "красиво" класс1.класс4.класс6.нужныйМетод
только в :labview: это не столь элегантно и опять же надо вызвать последовательно 4 функции (три из которых - data member access)

Да какой же я "старший брат", я ведь только учусь и в комментах умничаю.. Но по идее так и придеться вызывать метод класса 6. Но то же будет и с сабвиайками - если они будут вызываться вложенными, то каждая из них будет вызывать другую...
А текстах это, кстати, будет то же самое. Ведь каждый вызов типа классА.классБ - означает что из класса А Вы можете достучаться до класса Б, а значит там есть accessor для его вызова извне, или спец. методы. Что-то типа этого - https://stackoverflow.com/questions/385 ... ther-class.
Тут вопрос в другом - нужно ли класс 6 постоянно держать внутри класса 1? Может ли быть класс 6 вне класса 4, чтобы класс 1 = класс 2 + класс 3 + класс 6 + (класс 5)? В этом случае все зависит от задачи - зачем построена такая иерархия, и такие связи между классами; оптимальна ли она; не перебор ли это...
Мы делили апельсин - много наших полегло...
User avatar
Kosist
leader
leader
 
Posts: 877
Joined: 21 Feb 2011, 23:44
Medals: 2
Activity (1) Gold (1)
LabVIEW Version: 2013-2017
Karma: 246
CLAD I/O VIP students

Re: "накладные расходы" при работе программы

Postby taras_33 on 15 Aug 2018, 20:04

C:\Program Files (x86)\National Instruments\LabVIEW xxxx\examples\Channels\Replacing The Function At The Heart Of An Algorithm At Run Time

У меня установленном примере ошибка - lesson 4(LV2016)

Очепятка.png


Вообще OOP мощная штука, особенно в связке с actor framework, да и с HAL поработать... Вот почитайте особенно коментарии после статьи...
А вот каналы ни разу не использовал, нужно будет почитать о них (это я все об упомянутом примере из LV2016).
Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the Universe trying to produce bigger and better idiots.
So far, the Universe is winning!
User avatar
taras_33
adviser
adviser
 
Posts: 232
Joined: 31 Oct 2009, 18:25
Location: Minsk -> Miami
Medals: 1
Activity (1)
LabVIEW Version: 2016
Karma: 118
CLD VIP

Re: "накладные расходы" при работе программы

Postby IvanLis on 15 Aug 2018, 22:25

Artem.spb wrote:Начинаю разбиваnь данные на классы и...
для примера
класс 1 = класс 2 + класс 3 + класс 4
класс 4 = класс 5 + класс 6
И в программе я работаю с классом 1.
нужно вызвать метод класса 6.

Варианта два в моей голове.
1) класс 1 имеет метод, вызывающий метод "4", который вызывает "6"
итого, на вызов одной функции я пишу 3 :crazy:

2) то, что в текстах выглядит "красиво" класс1.класс4.класс6.нужныйМетод


Исходя из принципа "наследования", если нужны методы класса 6 в классе 1, то он должен быть включен в иерархию как базовый (или родительский), тогда получится:
Code: Select all
класс 1 = класс 2  + класс 3 + класс 4 + класс 6
класс 4 = класс 5 + класс 6

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

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

Короче не люблю я эти классы тоже.
Там трактуется все по разному, сколько людей, столько и мнений. Единого - стандартизованного подхода нет. Даже профи не могут придти к единому мнению, некоторые в открытую называют ООП "злом". Используя ОПП надеясь лишь на то, что компилятор поймет тебя верно и сделает все правильно :suicide: , и не придется идти стройным маршем сквозь десяток объектов, чтобы узнать значение параметра суперкласса... :vampire:
Да и прикручивание ООП к языку программирования, который изначально не создавался для этого, на мой взгляд не очень. Есть же языки типа Java, которые изначально создавались как ООП, так там все через классы делается.
User avatar
IvanLis
professor
professor
 
Posts: 4628
Joined: 02 Dec 2009, 17:44
Location: СССР
Medals: 7
Activity (2) Professionalism (1) Tutorials (1) Gold (1) Man of the year 2012 (1)
Автор (1)
LabVIEW Version: 2010
Karma: 727
hardware VIP bloggers teachers

Re: "накладные расходы" при работе программы

Postby Vitekkz88 on 16 Aug 2018, 07:15

Чтобы прикрутить ООП и модель акторов в проект - нужно хорошо проработать архитектуру самого проекта, ведь эти технологии уместны далеко не всегда. А чтобы не столкнуться с ситуацией вызова метода класса 6 классом 1 - нужно выбрать подходящий шаблон проектирования(он же паттерн) и проработать интерфейсы и сами классы. То, что описал Артём - это классический пример ловушки, в которую разработчик сам себя загоняет.
Мне это напомнило ситуацию, описанную в книге Эрика и Элизабет Фримен "Паттерны проектирования", когда программист писал апликуху с уточками, затем его попросили добавить пару фич(чтоб утки летали и крякали), а потом оказалось что часть уток должны быть резиновые и летать не умеют, одни крякают, а другие нет + добавить разное поведение... и как это привело к рефакторингу всего приложения. Если в ООП-языках типа Java об этом приходится думать постоянно: архитектуру классов и интерфейсов проработать, шаблоны выбрать, что-то допилить или внедрить, то в случае с LabVIEW всё проще.
Проще в том плане, что можно программировать по классике, а можно и через ООП. Отсюда вытекает следующее: LabVIEW не обязывает разработчика использовать ООП-стиль. А коль и по классике всё работает(не надо утрировать и примеров дурацких), то следует сосредоточиться на чистоте кода, например, или на изучении технологий более широкого спектра(отнюдь не LabVIEW-шных). Я аналогично рассуждаю: прикручивание ООП к языку программирования, который изначально не создавался для этого, на мой взгляд не очень.
Если корпоративная этика будет таковой, что ничего кроме LVOOP - то без проблем пересяду на эти рельсы.
Инженер - это открыто светящийся интеллект, свободный и не обидный юмор, это легкость и широта мысли...Это воспитанность, тонкость вкусов, хорошая речь, плавно согласованная и без сорных словечек...
-А. И. Солженицын
User avatar
Vitekkz88
expert
expert
 
Posts: 1044
Joined: 21 Jan 2014, 15:45
Location: Томск
Medals: 3
Activity (1) Silver (1) Автор (1)
LabVIEW Version: 12,13,14
Karma: 301
hardware I/O VIP

Re: "накладные расходы" при работе программы

Postby Artem.spb on 16 Aug 2018, 11:02

IvanLis wrote:Исходя из принципа "наследования", если нужны методы класса 6 в классе 1, то он должен быть включен в иерархию как базовый (или родительский), тогда получится:
Code: Select all
класс 1 = класс 2  + класс 3 + класс 4 + класс 6
класс 4 = класс 5 + класс 6

Ни что не мешает наследовать свойства и методы класса 6 в других (даже множестве) потомках.

Я говорю о другом. Не о родителях-потомках, а о соединении группы классов в надклассы.
На примерах, чтобы было понятнее.
Класс "Дом" = стены + водопровод + электричество.
электричество = счётчик + проводка + выключатели
ну и т.д.
надо включить свет ->
Дом.электричество.Выключатель.Включить

так там все через классы делается.

звучит как "там всё через ... делается" :)

некоторые в открытую называют ООП "злом"

Ни разу такого не встречал, хотя в ООП не много копался.
Есть подозрение, что дело не в ООП, а в росте сложности сиcтем, что неизбежно тянет вероятность ошибок.
Artem.spb
expert
expert
 
Posts: 1399
Joined: 31 Jul 2011, 23:05
Medals: 2
Activity (1) Автор (1)
LabVIEW Version: 12,14,15
Karma: 239
CLD hardware I/O VIP freelance

Re: "накладные расходы" при работе программы

Postby taras_33 on 16 Aug 2018, 14:22

Достаточно часто общаюсь с местными инженерами - программистами, как выяснилось они редко используют ООП в чистом виде, только "в связке" с AF, в кавычках потому что сам AF построен на ООП. Этой же стратегии придерживаюсь и я. Помимо программирования на LabVIEW, по работе приходиться заниматься ARM контроллерами... Так вот я не задумываюсь как работает например драйвер тачскрина и "что там внутри", я просто беру библиотеку и использую. Нет ну конечно если ты мазохист и хочется позаниматься ногодрыгом вручную, придерживаясь таймингов, - флаг в руки, но зачем? Вот такую же философию я использую при работе с Actor Framework - для меня это своего рода "драйвер", который предоставляет очень удобный механизм управления параллельными процессами и передачей информации между ними. Кроме того что то добавить/убрать из/в проект-а, при правильной организации архитектуры, достаточно легко - ведь актеры это независимые модули, как следствие экономит кучу времени, а оно очень ценное... Так что Holly-war разводить бессмысленно, каждому свое...

P.S. При изучении AF многое почерпнул из этого примера
Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the Universe trying to produce bigger and better idiots.
So far, the Universe is winning!
User avatar
taras_33
adviser
adviser
 
Posts: 232
Joined: 31 Oct 2009, 18:25
Location: Minsk -> Miami
Medals: 1
Activity (1)
LabVIEW Version: 2016
Karma: 118
CLD VIP

Re: "накладные расходы" при работе программы

Postby taras_33 on 20 Aug 2018, 03:56

Для подготовки на получение CLD сертификата, в свое время мне рекомендовали книгу Effective LabVIEW Programming. Купил - понравилось. Там есть шесть примеров CLD с подробным разбором кода.
Но я ее здесь упоминаю потому как, помимо всего остального, в книге неплохо объясняется ООП, а в главе 25, достаточно подробно и понятно рассказывается об "Inheritance and Composition" на примере Wash Controller, так что советую. Кроме того прилагаюстя примеры, упоминаемые в книге (после покупки доступен для скачивания архив).
Думаю если порыться и инете, то можно нарыть в pdf формате, возможно даже с примерами - eMule в помощь.
Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the Universe trying to produce bigger and better idiots.
So far, the Universe is winning!
User avatar
taras_33
adviser
adviser
 
Posts: 232
Joined: 31 Oct 2009, 18:25
Location: Minsk -> Miami
Medals: 1
Activity (1)
LabVIEW Version: 2016
Karma: 118
CLD VIP


Return to Модели программирования

Who is online

Users browsing this forum: No registered users and 1 guest

cron