Об эффективности виртуальных функций
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 04.08.24 20:19
Оценка:
Всю жизнь был уверен, что оценки вроде "виртуальные функции сильно снижают быстродействие" идут от неграмотных гуманитариев, которые где-то слышали звон, а потом рожают на его основе заумные тексты, которые потом цитируют технари, совершенно незнакомые с языком. Но почитал описании истории языка от Страуструпа (я читал несколько его книг, но истории раньше почему-то не попадалось), где он пишет, что многим программистам, в том числе системным, "было трудно поверить в то, что виртуальные функции могут быть достаточно быстрыми".

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

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

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

Кому-нибудь удавалось заметно снизить быстродействие заменой обычных функций на виртуальные? Ну, кроме случаев совсем уж плохого проектирования.
Re: Об эффективности виртуальных функций
От: opfor  
Дата: 04.08.24 20:25
Оценка:
Здравствуйте, Евгений Музыченко, Вы писали:

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


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

Кстати, почему они называются виртуальными? Дурацкое название.
Страуструп придумал?
Re: Об эффективности виртуальных функций
От: Stanislav V. Zudin Россия  
Дата: 04.08.24 20:46
Оценка: +1
Здравствуйте, Евгений Музыченко, Вы писали:

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


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


На борландовском компиляторе (ещё в ДОСе) обращение к статическим переменным было на порядок быстрее, чем к мемберам класса.
В Ваткомовском компиляторе такой проблемы уже не было.

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

Ну и да, в каких-то задачах косвенный вызов может стоить дополнительных тактов и может дать некоторое замедление — лишние микросекунды. Для сурового риалтайма может быть важным.
Мы в своих задачах таким не заморачивались — все ускорения достигались за счёт алгоритмов.
_____________________
С уважением,
Stanislav V. Zudin
Re[2]: Об эффективности виртуальных функций
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 04.08.24 20:51
Оценка:
Здравствуйте, opfor, Вы писали:

O>Может на какой-то машине вроде спектрума или realtime микроконтроллеров это возможно, где метод может вызываться много раз за цикл.


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

O>Кстати, почему они называются виртуальными? Дурацкое название.


Вы в курсе, что virtual — это "действительный", "фактический"?
Re[2]: Об эффективности виртуальных функций
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 04.08.24 20:58
Оценка:
Здравствуйте, Stanislav V. Zudin, Вы писали:

SVZ>На борландовском компиляторе (ещё в ДОСе) обращение к статическим переменным было на порядок быстрее, чем к мемберам класса.


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

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

SVZ>В Ваткомовском компиляторе такой проблемы уже не было.


SVZ>в каких-то задачах косвенный вызов может стоить дополнительных тактов и может дать некоторое замедление — лишние микросекунды. Для сурового риалтайма может быть важным.


В те времена, когда одно-два обращения к памяти занимали микросекунды, "суровый реалтайм" даже не помышляли писать даже на C, не говоря уже о C++.

SVZ>Мы в своих задачах таким не заморачивались — все ускорения достигались за счёт алгоритмов.


Дык, о том и речь.
Re[3]: Об эффективности виртуальных функций
От: opfor  
Дата: 04.08.24 21:16
Оценка:
Здравствуйте, Евгений Музыченко, Вы писали:

ЕМ>Вы в курсе, что virtual — это "действительный", "фактический"?


Нет, не в курсе:

Virtual:
Existing in the mind, especially as a product of the imagination
Existing or resulting in essence or effect though not in actual fact, form, or name
Created, simulated, or carried on by means of a computer or computer network

Re[3]: Об эффективности виртуальных функций
От: Stanislav V. Zudin Россия  
Дата: 04.08.24 21:22
Оценка:
Здравствуйте, Евгений Музыченко, Вы писали:

SVZ>>На борландовском компиляторе (ещё в ДОСе) обращение к статическим переменным было на порядок быстрее, чем к мемберам класса.


ЕМ>Не помню такого. Может, там где-то одна лишняя команда и затесывалась, но чтоб на порядок — не было.


Подробностей уже не помню, кажется, компилятор делал вычисление адреса мембера класса в рантайме в лоб — с несколькими уровнями косвенности, а со статическими переменными обращался напрямую по адресу.

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


Версию компилятора уже не помню. Не исключено, что в последующих версиях этот косяк был поправлен, но, код уже написан, я пришел в тот проект в 97г, в 98 мы портировали его на винду. И, кажется, он до сих пор используется в неизменном виде. 💪

SVZ>>в каких-то задачах косвенный вызов может стоить дополнительных тактов и может дать некоторое замедление — лишние микросекунды. Для сурового риалтайма может быть важным.


ЕМ>В те времена, когда одно-два обращения к памяти занимали микросекунды, "суровый реалтайм" даже не помышляли писать даже на C, не говоря уже о C++.


Я уже говорю про сейчас — какой-нибудь HFT, передача по сети и т.п.
_____________________
С уважением,
Stanislav V. Zudin
Re[4]: Об эффективности виртуальных функций
От: · Великобритания  
Дата: 04.08.24 21:41
Оценка: +1
Здравствуйте, opfor, Вы писали:

o> ЕМ>Вы в курсе, что virtual — это "действительный", "фактический"?

o> Нет, не в курсе:
Синоним "почти", например в рекламе часто попадается virtually indestructible.

virtual: almost a particular thing or quality

She suffered a virtual breakdown when her marriage broke up.

https://dictionary.cambridge.org/dictionary/english/virtual
avalon/3.0.0
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Re: Об эффективности виртуальных функций
От: vsb Казахстан  
Дата: 05.08.24 02:49
Оценка: +4
Сотни тысяч раз можно и функцию на питоне вызывать. Наверное те, кто переживает за виртуальные функции, собираются их вызывать хотя бы миллиард раз в секунду.
Re[3]: Об эффективности виртуальных функций
От: σ  
Дата: 05.08.24 03:46
Оценка: +3
O>>Кстати, почему они называются виртуальными? Дурацкое название.

ЕМ>Вы в курсе, что virtual — это "действительный", "фактический"?


Почти действительный
Re: Об эффективности виртуальных функций
От: Nuzhny Россия https://github.com/Nuzhny007
Дата: 05.08.24 04:04
Оценка: +2
Здравствуйте, Евгений Музыченко, Вы писали:

ЕМ>Все эти люди старательно избегали любой косвенности, указатели/ссылки использовали лишь в самых крайних случаях?


Беседовал когда-то с челом из HFT, так его беспокоили не сами вызовы виртуальных функций, а наличие таблицы виртуальных функций, которая увеличивала размер класса. Ну и массовое создание/удаление множества мелких объектов без виртуальности происходило заметно быстрее. Сериализация — вот это всё.
Я в детали не вдавался, это было на какой-то конференции по С++, поэтому на дополнительные вопросы ответить не смогу.
Re: Об эффективности виртуальных функций
От: karbofos42 Россия  
Дата: 05.08.24 05:15
Оценка:
Здравствуйте, Евгений Музыченко, Вы писали:

ЕМ>Откуда вообще могло взяться такое опасение в профессиональной-то среде?


Можно у разработчиков STL спросить почему они не сделали абстракции в виде Collection/ICollection как в библиотеках той же Java или C#.
Удобно ведь было бы в метод принимать просто коллекцию, получать какой-то абстрактный итератор для перебора или через виртуальный метод add добавить пару элементов.
Вместо этого приходится писать методы конкретно под std::vector и никакой std::set не передашь.
Re[2]: Об эффективности виртуальных функций
От: so5team https://stiffstream.com
Дата: 05.08.24 06:31
Оценка:
Здравствуйте, karbofos42, Вы писали:

K>Можно у разработчиков STL спросить почему они не сделали абстракции в виде Collection/ICollection как в библиотеках той же Java или C#.


Вроде бы об этом Страуструп в своей книге "Дизайн и эволюция" писал. Как и об отсутствии единого базового класса Object, как в во многих ООЯП.

K>Вместо этого приходится писать методы конкретно под std::vector и никакой std::set не передашь.


Это какой-то странный код, если ему фиолетово, используется ли std::vector или std::set.
Re[4]: Об эффективности виртуальных функций
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 05.08.24 08:52
Оценка:
Здравствуйте, Stanislav V. Zudin, Вы писали:

SVZ>кажется, компилятор делал вычисление адреса мембера класса в рантайме в лоб — с несколькими уровнями косвенности


class If {

  public:

  virtual void f1 () = 0;
  virtual void f2 () = 0;

};

void f (If & i) {

  i.f1 ();
  i.f2 ();

}


TC++ 1.0:

@f$qr2If    proc    near
    push    bp
    mov    bp,sp
    push    si
    mov    si,word ptr [bp+4]
   ;    
   ;    
   ;      i.f1 ();
   ;    
    push    si
    mov    bx,word ptr [si]
    call    word ptr [bx]
    pop    cx
   ;    
   ;      i.f2 ();
   ;    
    push    si
    mov    bx,word ptr [si]
    call    word ptr [bx+2]
    pop    cx
   ;    
   ;    
   ;    }
   ;    
    pop    si
    pop    bp
    ret    
@f$qr2If    endp


Я тут вижу только лишние push/pop, но получить из-за них сколько-нибудь ощутимое снижение быстродействия нужно очень-очень постараться.

ЕМ>>В те времена, когда одно-два обращения к памяти занимали микросекунды, "суровый реалтайм" даже не помышляли писать даже на C, не говоря уже о C++.


SVZ>Я уже говорю про сейчас — какой-нибудь HFT, передача по сети и т.п.


А сейчас — тем более, десяток-другой лишних обращений к памяти — ничто по сравнению с затратами на основную обработку данных и временем ожидания ответа устройств.
Re[2]: Об эффективности виртуальных функций
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 05.08.24 09:01
Оценка:
Здравствуйте, Nuzhny, Вы писали:

N>Беседовал когда-то с челом из HFT, так его беспокоили не сами вызовы виртуальных функций, а наличие таблицы виртуальных функций, которая увеличивала размер класса.


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

N>Ну и массовое создание/удаление множества мелких объектов без виртуальности происходило заметно быстрее. Сериализация — вот это всё.


Тоже странно. Такое ощущение, что было как-то неправильно спроектировано.
Re[2]: Об эффективности виртуальных функций
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 05.08.24 09:04
Оценка: 10 (1) +1
Здравствуйте, karbofos42, Вы писали:

K>Вместо этого приходится писать методы конкретно под std::vector и никакой std::set не передашь.


Насколько я понимаю, они делали простые контейнеры вроде vector/list так, чтобы после оптимизации получался предельно эффективный код, не уступающий коду со встроенными массивами и ручными списками. В принципе, это правильно, иначе нареканий на STL было бы гораздо больше.
Re[3]: Об эффективности виртуальных функций
От: so5team https://stiffstream.com
Дата: 05.08.24 09:16
Оценка: :)
Здравствуйте, Евгений Музыченко, Вы писали:

N>>Ну и массовое создание/удаление множества мелких объектов без виртуальности происходило заметно быстрее. Сериализация — вот это всё.


ЕМ>Тоже странно. Такое ощущение, что было как-то неправильно спроектировано.


Ну так в HFT же криворукие идиоты работают, половину которых набрали по объявлению, а вторую половину -- по блату.
Re[3]: Об эффективности виртуальных функций
От: · Великобритания  
Дата: 05.08.24 09:18
Оценка:
Здравствуйте, Евгений Музыченко, Вы писали:

ЕМ> N>Беседовал когда-то с челом из HFT, так его беспокоили не сами вызовы виртуальных функций, а наличие таблицы виртуальных функций, которая увеличивала размер класса.

ЕМ> Они использовали хотя бы миллионы разных классов? Таблица-то общая на весь класс, а в каждом объекте добавляется только ее адрес. Чтобы получить заметное (в нынешних масштабах) увеличение расходов, они должны создавать хотя бы миллионы объектов очень маленького размера (десяток-другой байт), иначе этот прирост теряется на фоне размера самого объекта.
Так примерно оно и есть. Какой-нибудь там Order будет i64 цена, i64 количество, i16 currency pair, и неск байт всяких атрибутов. И в памяти лежат миллионы таких.
avalon/3.0.0
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Re[4]: Об эффективности виртуальных функций
От: · Великобритания  
Дата: 05.08.24 09:20
Оценка: :)
Здравствуйте, so5team, Вы писали:

s> Ну так в HFT же криворукие идиоты работают, половину которых набрали по объявлению, а вторую половину -- по блату.

Иди туда, спроектируй всё по правильному — заработаешь миллионы и получишь мировую известность.
avalon/3.0.0
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Re[5]: Об эффективности виртуальных функций
От: so5team https://stiffstream.com
Дата: 05.08.24 09:27
Оценка: +1 :)
Здравствуйте, ·, Вы писали:

s>> Ну так в HFT же криворукие идиоты работают, половину которых набрали по объявлению, а вторую половину -- по блату.

·>Иди туда, спроектируй всё по правильному — заработаешь миллионы и получишь мировую известность.

Не-не-не, у меня с сарказмом все нормально, в отличии от.
Re[6]: Об эффективности виртуальных функций
От: · Великобритания  
Дата: 05.08.24 09:41
Оценка:
Здравствуйте, so5team, Вы писали:

s> ·>Иди туда, спроектируй всё по правильному — заработаешь миллионы и получишь мировую известность.

s> Не-не-не, у меня с сарказмом все нормально, в отличии от.
Прошу прощения, не распознал.
avalon/3.0.0
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Re[3]: Об эффективности виртуальных функций
От: karbofos42 Россия  
Дата: 05.08.24 09:55
Оценка:
Здравствуйте, Евгений Музыченко, Вы писали:

ЕМ>Насколько я понимаю, они делали простые контейнеры вроде vector/list так, чтобы после оптимизации получался предельно эффективный код, не уступающий коду со встроенными массивами и ручными списками. В принципе, это правильно, иначе нареканий на STL было бы гораздо больше.


т.е. виртуальные итераторы и методы добавления/удаления элементов как это сделано в C# и Java, добавляют таки существенные накладные расходы, что разработчики STL от этого отказались?
Re[3]: Об эффективности виртуальных функций
От: karbofos42 Россия  
Дата: 05.08.24 10:02
Оценка:
Здравствуйте, so5team, Вы писали:

S>Вроде бы об этом Страуструп в своей книге "Дизайн и эволюция" писал. Как и об отсутствии единого базового класса Object, как в во многих ООЯП.


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

S>Это какой-то странный код, если ему фиолетово, используется ли std::vector или std::set.


Допустим, нужно сохранить коллекцию в json в виде массива [1,2,3] или что-то в этом духе.
Методу записи просто нужно перебрать все элементы коллекции, получить их значения и записать в json. Вектор там или множество — вообще же без разницы.
При чтении значений из json мне так же без разницы как там элементы хранятся, просто нужно их по очереди добавить в коллекцию.
Re[4]: Об эффективности виртуальных функций
От: so5team https://stiffstream.com
Дата: 05.08.24 10:10
Оценка:
Здравствуйте, karbofos42, Вы писали:

S>>Вроде бы об этом Страуструп в своей книге "Дизайн и эволюция" писал. Как и об отсутствии единого базового класса Object, как в во многих ООЯП.


K>Если мне не изменяет память, то разработчики STL максимально упарывались по производительности и потреблению памяти, чтобы работало и на утюгах.


Чтобы работал на утюгах -- это про проект Oak, из которого затем получился костыль под названием Java 1.0. Этот костыль затем в течении 10 лет дорабатывали чтобы он сравнялся по выразительности с C++ времен 1994-го года.

В C++ же идеология "не платишь за то что не используешь"(1)
Поэтому если программисту не нужен базовый Object, то значит его не должно быть и вовсе.

S>>Это какой-то странный код, если ему фиолетово, используется ли std::vector или std::set.


K>Допустим, нужно сохранить коллекцию в json в виде массива [1,2,3] или что-то в этом духе.

K>Методу записи просто нужно перебрать все элементы коллекции, получить их значения и записать в json. Вектор там или множество — вообще же без разницы.
K>При чтении значений из json мне так же без разницы как там элементы хранятся, просто нужно их по очереди добавить в коллекцию.

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

-----
(1) С некоторыми поправками "на ветер" и специфичность восприятия как "не используешь", так и "не платишь".
Re[2]: Об эффективности виртуальных функций
От: B0FEE664  
Дата: 05.08.24 10:32
Оценка:
Здравствуйте, karbofos42, Вы писали:

K>Можно у разработчиков STL спросить почему они не сделали абстракции в виде Collection/ICollection как в библиотеках той же Java или C#.

Это потребует дополнительного расхода памяти размером в один указатель на объект, что противоречит известному принципу про платёж.

K>Удобно ведь было бы в метод принимать просто коллекцию, получать какой-то абстрактный итератор для перебора или через виртуальный метод add добавить пару элементов.

K>Вместо этого приходится писать методы конкретно под std::vector и никакой std::set не передашь.

Перебор можно сделать через шаблонные функции, а вот добавление — не факт, что оно должно быть универсальным.
Впрочем, что мешает написать обёртку, которая будет принимать в конструкторе тип контейнера (или сам контейнер) и выставлять желаемый интерфейс? Такое можно написать за несколько часов без особого труда.
Однако, ICollection всё равно не получится сделать один на всех, ведь контейнеры шаблонные, а значит ICollection тоже будет шаблонным, т.е. ICollection<int> и ICollection<char> — это два разных типа.
Всё это из-за того, что в С++ до сих пор не добавили шаблонные виртуальные функции.
И каждый день — без права на ошибку...
Re[5]: Об эффективности виртуальных функций
От: karbofos42 Россия  
Дата: 05.08.24 10:55
Оценка:
Здравствуйте, so5team, Вы писали:

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


На практике не пишут в json и не перебирают коллекции?
Итераторы вроде бы для этого и придумали, чтобы они умели оптимально по соответствующим структурам ходить.
Зачем тогда в стандарт добавили цикл for для диапазонов?
Если я через шаблон или вручную продублирую метод для std::vector и std::set, где будет в итоге одинаковый цикл "for (auto& v: values)", то это нормально?
Или для vector и set нельзя одинаковый перебор использовать?
Re[3]: Об эффективности виртуальных функций
От: пффф  
Дата: 05.08.24 10:56
Оценка:
Здравствуйте, B0FEE664, Вы писали:

BFE>Перебор можно сделать через шаблонные функции, а вот добавление — не факт, что оно должно быть универсальным.

BFE>Впрочем, что мешает написать обёртку, которая будет принимать в конструкторе тип контейнера (или сам контейнер) и выставлять желаемый интерфейс? Такое можно написать за несколько часов без особого труда.


Да вроде уже готовое есть — inserter/back_inserter
Re[6]: Об эффективности виртуальных функций
От: so5team https://stiffstream.com
Дата: 05.08.24 11:02
Оценка: +2
Здравствуйте, karbofos42, Вы писали:

K>На практике не пишут в json


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

K>и не перебирают коллекции?


Для перебора коллекций отлично работают шаблоны. Уже много лет как.

А если кому-то нужно спрятать тип коллекции за каким-то непрозрачным фасадом, то это делается обычными классами с виртуальными методами в конкретном проекте. Без надобности вводить ICollection в стандартную библиотеку C++.

Принцип "не платим за то, что не используем" (при всех его оговорках) работает именно так.
Re[4]: Об эффективности виртуальных функций
От: · Великобритания  
Дата: 05.08.24 11:09
Оценка:
Здравствуйте, karbofos42, Вы писали:

k> т.е. виртуальные итераторы и методы добавления/удаления элементов как это сделано в C# и Java, добавляют таки существенные накладные расходы, что разработчики STL от этого отказались?

В этих яп есть gc и другие штуки, которые без инфы о типе в рантайме работать не могут. Поэтому это просто другой компромисс, вместо нулевых накладных расходов добавляются несколько вкусных вещей, как "бесплатность" виртуальных функций, gc и прочий jit и reflection.
avalon/3.0.0
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Re[4]: Об эффективности виртуальных функций
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 05.08.24 11:18
Оценка:
Здравствуйте, ·, Вы писали:

·>Какой-нибудь там Order будет i64 цена, i64 количество, i16 currency pair, и неск байт всяких атрибутов. И в памяти лежат миллионы таких.


А виртуальные функции сюда каким боком?
Re[3]: Об эффективности виртуальных функций
От: karbofos42 Россия  
Дата: 05.08.24 11:20
Оценка:
Здравствуйте, B0FEE664, Вы писали:

BFE>Это потребует дополнительного расхода памяти размером в один указатель на объект, что противоречит известному принципу про платёж.


т.е. ТС не прав про гуманитариев, виртуальные методы создают большие накладные расходы и на них действительно имеет смысл экономить?

BFE>Впрочем, что мешает написать обёртку, которая будет принимать в конструкторе тип контейнера (или сам контейнер) и выставлять желаемый интерфейс? Такое можно написать за несколько часов без особого труда.


В итоге в проекте будет какой-то зоопарк, а накладных расходов ещё больше, чем было бы с виртуальными методами изначально.
Хотя в плюсах наверно так принято, чтобы веселее было. Один интерфейс как в других языках — не интересно, а вот когда где-то vector, где-то QList или wxVector или ещё какой подобный класс — это весело и замечательно, особенно когда нужно из одного типа в другой данные гонять, т.к. у тебя есть vector, а нужный метод написан для QList.

BFE>Однако, ICollection всё равно не получится сделать один на всех, ведь контейнеры шаблонные, а значит ICollection тоже будет шаблонным, т.е. ICollection<int> и ICollection<char> — это два разных типа.

BFE>Всё это из-за того, что в С++ до сих пор не добавили шаблонные виртуальные функции.

так и пусть разные будут, лишь бы можно было в итоге написать без шаблонов и обёрток метод вида:
void process(collection<int>& items)
{
  for (auto& value: items)
  {
    ...
  }
}

и передать туда и std::vector<int> и std::set<int> и QList<int> (при условии конечно, что все они унаследуются от collection<int>)
Или всё же такое наследование и последующие виртуальные вызовы добавят увеличение потребления памяти, существенно снизит скорость работы и в плюсах так не принято?
Re[4]: Об эффективности виртуальных функций
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 05.08.24 11:24
Оценка:
Здравствуйте, karbofos42, Вы писали:

K>т.е. виртуальные итераторы и методы добавления/удаления элементов как это сделано в C# и Java, добавляют таки существенные накладные расходы, что разработчики STL от этого отказались?


Я, честно говоря, хз. Возможно, дело в том, что добавление возможности вызова виртуального итератора в базовый контейнер сразу же заметно добавляет накладных расходов для простейших контейнеров, а сделать такие шаблоны, чтоб эта возможность добавлялась без ненужных хвостов, не получилось. Ну, или просто не захотели.
Re[4]: Об эффективности виртуальных функций
От: so5team https://stiffstream.com
Дата: 05.08.24 11:26
Оценка: :)
Здравствуйте, karbofos42, Вы писали:

K>т.е. ТС не прав про гуманитариев


ТС сам гуманитарий и не озаботился даже тем, чтобы самому написать пару-тройку бенчмарков, чтобы сравнить.
Re[5]: Об эффективности виртуальных функций
От: karbofos42 Россия  
Дата: 05.08.24 11:28
Оценка:
Здравствуйте, ·, Вы писали:

·>В этих яп есть gc и другие штуки, которые без инфы о типе в рантайме работать не могут. Поэтому это просто другой компромисс, вместо нулевых накладных расходов добавляются несколько вкусных вещей, как "бесплатность" виртуальных функций, gc и прочий jit и reflection.


Не понимаю как тут gc и прочее помогают. Виртуальные методы и в C# и Java вызываются медленнее, чем "обычные", т.е. просто в этих языках решили, что общие интерфейсы коллекций с последующей виртуализацией — это адекватная плата за удобство (кому нужно — может всегда написать свою более оптимальную коллекцию). В C++ предпочли экономию по максимуму и не выводить стандартных интерфейсов для тех же коллекций.
Re[4]: Об эффективности виртуальных функций
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 05.08.24 11:31
Оценка:
Здравствуйте, so5team, Вы писали:

S>Ну так в HFT же криворукие идиоты работают, половину которых набрали по объявлению, а вторую половину -- по блату.


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

Поэтому там, где нужна предельная эффективность, до сих пор преобладают сишники. А плюсовики, изучавшие язык "сверху", вполне могут долгое время сохранять усвоенные когда-то предубеждения, что не мешает им писать достаточно эффективный код способами, которым они доверяют.
Re[5]: Об эффективности виртуальных функций
От: so5team https://stiffstream.com
Дата: 05.08.24 11:42
Оценка: :)
Здравствуйте, Евгений Музыченко, Вы писали:

S>>Ну так в HFT же криворукие идиоты работают, половину которых набрали по объявлению, а вторую половину -- по блату.


ЕМ>Зачем же именно так?


Потому что ваша ограниченность и гуманитарность уже подбешивает как тупизм Shmj. И ведь кто-то видит у вас репутацию "опытного разработчика"

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


Особенно их мало среди тех, кто занимается HFT. Ну и HPC заодно, чтобы два раза не вставать.

На всякий случай для предшествующего предложения тег:

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


На какой выборке вы делаете это заключение?

ЕМ>Поэтому там, где нужна предельная эффективность, до сих пор преобладают сишники.


На какой выборке вы делаете это заключение?
Отредактировано 05.08.2024 12:02 so5team . Предыдущая версия .
Re[6]: Об эффективности виртуальных функций
От: · Великобритания  
Дата: 05.08.24 11:46
Оценка:
Здравствуйте, karbofos42, Вы писали:

k> ·>В этих яп есть gc и другие штуки, которые без инфы о типе в рантайме работать не могут. Поэтому это просто другой компромисс, вместо нулевых накладных расходов добавляются несколько вкусных вещей, как "бесплатность" виртуальных функций, gc и прочий jit и reflection.

k> Не понимаю как тут gc и прочее помогают.
Я имел в виду, не то что gc помогает, а то что накладные расходы в виде указателя на тип нужны не эксклюзивно для виртуальных вызовов, но и для gc и ещё кучи фич.

k> Виртуальные методы и в C# и Java вызываются медленнее, чем "обычные", т.е. просто в этих языках решили, что общие интерфейсы коллекций с последующей виртуализацией — это адекватная плата за удобство (кому нужно — может всегда написать свою более оптимальную коллекцию).

В этих яп добавление интерфейса дополнительных расходов не добавит, т.к. инфа о типе уже есть. Иными словами, если выкинуть ICollection — станет только хуже.

k> В C++ предпочли экономию по максимуму и не выводить стандартных интерфейсов для тех же коллекций.

Потому что если просто ввести интерфейс, придётся добавить инфу о типе. Игра не стоит свеч.
avalon/3.0.0
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Re[5]: Об эффективности виртуальных функций
От: · Великобритания  
Дата: 05.08.24 11:50
Оценка:
Здравствуйте, Евгений Музыченко, Вы писали:

ЕМ> ·>Какой-нибудь там Order будет i64 цена, i64 количество, i16 currency pair, и неск байт всяких атрибутов. И в памяти лежат миллионы таких.

ЕМ> А виртуальные функции сюда каким боком?
Если проектировать "красиво", то удобнее будет иметь несколько типов, в зависимости от вида ордера (market/limit/stop/etc), т.к. они могут работать несколько по-разному. Всякий диспатчинг, однако, делают по битовым атрибутам и if/else/switch вместо виртуальных ф-ций.
avalon/3.0.0
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Re[5]: Об эффективности виртуальных функций
От: karbofos42 Россия  
Дата: 05.08.24 11:56
Оценка:
Здравствуйте, Евгений Музыченко, Вы писали:

ЕМ>Я, честно говоря, хз. Возможно, дело в том, что добавление возможности вызова виртуального итератора в базовый контейнер сразу же заметно добавляет накладных расходов для простейших контейнеров, а сделать такие шаблоны, чтоб эта возможность добавлялась без ненужных хвостов, не получилось. Ну, или просто не захотели.


По-моему это идеология языка. Людям нравится городить хитрые оптимизации и вот так забавляются.
В других языках просто выбрали удобство за счёт небольшой платы. В С++ и в стандартных библиотеках на тех же виртуальных вызовах экономят, что закономерно идёт как рекомендация.
Я помню ещё холивары на счёт исключений. Одни писали, что этот механизм крутой и удобный. Другие топили за коды ошибок, т.к. исключение — это же создание объекта и прочие непозволительно дорогие накладные расходы.
На мой взгляд для большинства софта подобная экономия на спичках (виртуальных методах) вообще незаметна. Но если по такому не упарываться, то непонятно зачем на C++ писать, а не взять что-то более удобное
Re[6]: Об эффективности виртуальных функций
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 05.08.24 11:57
Оценка:
Здравствуйте, ·, Вы писали:

·>Если проектировать "красиво", то удобнее будет иметь несколько типов, в зависимости от вида ордера (market/limit/stop/etc), т.к. они могут работать несколько по-разному. Всякий диспатчинг, однако, делают по битовым атрибутам и if/else/switch вместо виртуальных ф-ций.


В такой ситуации в полный рост встает вопрос о разнесении разных типов по собственным контейнерам, чтобы вынести проверку типа как можно выше. Но это, понятно, только после измерений на конкретных задачах.
Re[6]: Об эффективности виртуальных функций
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 05.08.24 12:11
Оценка:
Здравствуйте, karbofos42, Вы писали:

K>В других языках просто выбрали удобство за счёт небольшой платы.


Плата, считающаяся в большинстве языков "небольшой", в задачах, где традиционно применяется C++, легко может оказаться неприемлемой.

K>В С++ и в стандартных библиотеках на тех же виртуальных вызовах экономят, что закономерно идёт как рекомендация.


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

В C++ проблема в том, что попытки придать шаблону бОльшую гибкость и универсальность нередко ведут к сильному усложнению и необходимости применения трюков, которые трудно сопровождать и отлаживать.

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


А с этим проблема в том, что нет механизмов, промежуточных по сложности и накладным расходам. Коды ошибок приходится распространять наверх почти целиком вручную, мало что можно приспособить для автоматизации — в основном лишь для ловли собственных ошибок. Добавление исключений сразу же тянет за собой и механизмы создания/копирования объектов исключений, и RTTI, а между этими крайностями ничего нет. Во многих случаях было бы достаточно какого-нибудь легковесного механизма, передающего наверх только фундаментальные типы (простые значения или указатели).

K>На мой взгляд для большинства софта подобная экономия на спичках (виртуальных методах) вообще незаметна. Но если по такому не упарываться, то непонятно зачем на C++ писать, а не взять что-то более удобное


Идея разумная. Но удобство C++ как раз в том, что на нем можно писать всё.
Re[7]: Об эффективности виртуальных функций
От: so5team https://stiffstream.com
Дата: 05.08.24 12:18
Оценка: -2 :))
Здравствуйте, Евгений Музыченко, Вы писали:

ЕМ>Но удобство C++ как раз в том, что на нем можно писать всё.


Евгений, блин, уже лет 20 как пора забыть про эту чушь.
Re[7]: Об эффективности виртуальных функций
От: · Великобритания  
Дата: 05.08.24 12:21
Оценка:
Здравствуйте, Евгений Музыченко, Вы писали:

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

Так контейнеры не просто так контейнят, а в соответствии с бизнес-логикой, например, упорядоченно по времени обработки.
avalon/3.0.0
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Re[2]: Об эффективности виртуальных функций
От: andyp  
Дата: 05.08.24 12:54
Оценка: +1
Здравствуйте, karbofos42, Вы писали:

K>Удобно ведь было бы в метод принимать просто коллекцию, получать какой-то абстрактный итератор для перебора или через виртуальный метод add добавить пару элементов.

K>Вместо этого приходится писать методы конкретно под std::vector и никакой std::set не передашь.

Как должен выглядеть такой обобщенный add для vector и set? Куда и что он втыкать будет — не понятно. С абстрактным итератором тоже неясно — как это будет работать и где гарантии, что ты посетишь все элементы коллекции. Да даже просто изменение элементов в одном случае структуру коллекции не меняет, а в другом — меняет. Т.е. имхо пока даже почвы для обобщения немного. Если твои функции предполагают, что коллекция в процессе не меняется, то любая вьюха (наверное, на языке стандарта это называется range???), состоящая из пары итераторов или еще чего — подойдет, чтобы пробежаться по всем элементам. Зачем для этого иметь общий интерфейс — я , но то путь явы и шарпов.
Re[3]: Об эффективности виртуальных функций
От: karbofos42 Россия  
Дата: 05.08.24 13:27
Оценка: +1 :)
Здравствуйте, andyp, Вы писали:

A>Как должен выглядеть такой обобщенный add для vector и set? Куда и что он втыкать будет — не понятно.


Это очень просто решается путём документирования поведения, что для vector этот самый add — это добавление в конец коллекции, для set всё проще и это тот же insert.
В тех же шарпах и явах с этим живут и проблем не испытывают.

A>С абстрактным итератором тоже неясно — как это будет работать и где гарантии, что ты посетишь все элементы коллекции.


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

A>Да даже просто изменение элементов в одном случае структуру коллекции не меняет, а в другом — меняет.


И как это сейчас работает? Просто программист имеет знания и вручную следит или волшебство С++ работает какое-то?
Что тут изменится, если у коллекций и итераторов появятся общие базовые классы?

A>Т.е. имхо пока даже почвы для обобщения немного.


Ну, да. В других языках как-то обобщилось, а в С++ — никак. Я и говорю, что это упоротая идеология языка.
Распихать по стандарту кучу UB — легко. Добавить в синтаксис языка кучу возможностей опечататься и выстрелить себе в ногу — пожалуйста.
Договориться, что collection.add() для вектора — это аналог метода push_back — непонятно как с этим потом жить.

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


А если нужно добавлять элементы в коллекцию? А вьюхи бесплатные и удобные, чтобы такое городить? Не выходит в итоге, что с общим интерфейсом и виртуальными методами работа с коллекцией была бы быстрее и удобнее, чем создавать вьюхи и пробираться через них? Но такой путь плюсов
Re[4]: Об эффективности виртуальных функций
От: so5team https://stiffstream.com
Дата: 05.08.24 13:40
Оценка:
Здравствуйте, karbofos42, Вы писали:

K>Ну, да. В других языках как-то обобщилось, а в С++ — никак. Я и говорю, что это упоротая идеология языка.


Вы, по видимому, просто не застали первую Java. Там ведь коллекции были нетипизированными в том смысле, что хранился всегда Object. Не важно, запихивали ли вы в коллекцию String или File, или DateTime, все равно там лежал Object. И доставался назад тоже Object, который потом вручную нужно было кастить к нужному вам типу (и получать иногда исключения, если программист забыл что куда укладывал).

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

Только вот в C++ не было базового класса Object.
А значит и коллекции нужно было строить по другому.

Вот и построили их на базе шаблонов.
Re[5]: Об эффективности виртуальных функций
От: karbofos42 Россия  
Дата: 05.08.24 14:02
Оценка:
Здравствуйте, so5team, Вы писали:

S>Вы, по видимому, просто не застали первую Java.


И в Java и в C# Generic'и появились не с первой версии, я в курсе. И при всей внешней синтаксической похожести они работают по-разному в этих языках.

S>Только вот в C++ не было базового класса Object.

S>А значит и коллекции нужно было строить по другому.

S>Вот и построили их на базе шаблонов.


И что мешает эти уже шаблонные классы коллекций унаследовать от таких же шаблонных общих базовых классов?
  Вот так в чём проблема сделать?
#include <iostream>

template <typename T>
class collection
{
public:
  virtual void add(T item) = 0;
};

template<typename T>
class vector: public collection<T>
{
public:
  virtual void add(T item)
  {
      std::cout << "vector add " << item << std::endl;
  }
};

template<typename T>
class set: public collection<T>
{
public:
  virtual void add(T item)
  {
      std::cout << "set add " << item << std::endl;
  }
};

void fill_data(collection<int>& items)
{
    items.add(10);
}

int main()
{
    vector<int> v;
    fill_data(v);
    
    set<int> s;
    fill_data(s);

    return 0;
}
Re[5]: Об эффективности виртуальных функций
От: пффф  
Дата: 05.08.24 14:04
Оценка:
Здравствуйте, Евгений Музыченко, Вы писали:

ЕМ>Поэтому там, где нужна предельная эффективность, до сих пор преобладают сишники.


Или плюсовики, которые уделяют внимание вопросам производительности.


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


И это прекрасно, что язык такое позволяет
Re[4]: Об эффективности виртуальных функций
От: andyp  
Дата: 05.08.24 14:08
Оценка: +1
Здравствуйте, karbofos42, Вы писали:

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


A>>Как должен выглядеть такой обобщенный add для vector и set? Куда и что он втыкать будет — не понятно.

K>Это очень просто решается путём документирования поведения, что для vector этот самый add — это добавление в конец коллекции, для set всё проще и это тот же insert.
K>В тех же шарпах и явах с этим живут и проблем не испытывают.

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

A>>С абстрактным итератором тоже неясно — как это будет работать и где гарантии, что ты посетишь все элементы коллекции.

K>Так же как и сейчас работает. Просто вызываться будут виртуальные методы некоего базового итератора, а фактически реализация будет та же, что сейчас.

Ну сейчас это просто не работает После того, как ты изменил элемент в std::set (erase-insert) тебе обещают, что все твои сохраненные итераторы будут указывать на что-то валидное. Но это не значит, что с их помощью ты обежишь всю коллекцию и ничего не пропустишь.

A>>Да даже просто изменение элементов в одном случае структуру коллекции не меняет, а в другом — меняет.

K>И как это сейчас работает? Просто программист имеет знания и вручную следит или волшебство С++ работает какое-то?
K>Что тут изменится, если у коллекций и итераторов появятся общие базовые классы?

Программист имеет знание, с какой именно коллекцией он работает. Это ж важно.

A>>Т.е. имхо пока даже почвы для обобщения немного.

K>Ну, да. В других языках как-то обобщилось, а в С++ — никак. Я и говорю, что это упоротая идеология языка.
K>Распихать по стандарту кучу UB — легко. Добавить в синтаксис языка кучу возможностей опечататься и выстрелить себе в ногу — пожалуйста.
K>Договориться, что collection.add() для вектора — это аналог метода push_back — непонятно как с этим потом жить.

Договориться — имхо вообще негодный подход. Имхо, Степанов правильно сделал, что не стал делать общий базовый класс для коллекций. Вот почитал доку на Яву и увидел, что их обобщение коллекции это просто нечто, по чему можно итерировать. И все, Карл. Чтобы что-то более значимое запилить, нужно что-то новое о коллекциях понять имхо. Существующее обобщение никак не помогает. Хреновая абстракция, имхо, этот общий базовый класс.

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

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

А что дорогого в паре итераторов или паре итератор + счетчик? Обобщенный код под такое вполне себе пишется. Сделай своему алгоритму, которому пофиг на тип коллекции, такой интерфейс и дело в шляпе, без всех этих иерархий классов.
Отредактировано 05.08.2024 14:12 andyp . Предыдущая версия .
Re[6]: Об эффективности виртуальных функций
От: пффф  
Дата: 05.08.24 14:12
Оценка: +2
Здравствуйте, karbofos42, Вы писали:

K>На мой взгляд для большинства софта подобная экономия на спичках (виртуальных методах) вообще незаметна. Но если по такому не упарываться, то непонятно зачем на C++ писать, а не взять что-то более удобное


В C++ контенеры универсальные. И вполне могут содержать миллионы и более объектов на некоторых задачах. И вполне вероятно, что над этими объектами могут часто производится легкие операции, и тут виртуальность уже может добавить времени.
Ну и, не буду утверждать, но предполагаю, что косвенность мешает оптимизатору
Re[4]: Об эффективности виртуальных функций
От: пффф  
Дата: 05.08.24 14:21
Оценка:
Здравствуйте, karbofos42, Вы писали:

BFE>>Впрочем, что мешает написать обёртку, которая будет принимать в конструкторе тип контейнера (или сам контейнер) и выставлять желаемый интерфейс? Такое можно написать за несколько часов без особого труда.


K>В итоге в проекте будет какой-то зоопарк,


Не будет


K>а накладных расходов ещё больше, чем было бы с виртуальными методами изначально.


Компилятор соптимизирует


K>Хотя в плюсах наверно так принято, чтобы веселее было. Один интерфейс как в других языках — не интересно, а вот когда где-то vector, где-то QList или wxVector или ещё какой подобный класс — это весело и замечательно, особенно когда нужно из одного типа в другой данные гонять, т.к. у тебя есть vector, а нужный метод написан для QList.


Наличие vector, QList или wxVector — это проблемы сторонних библиотек. Как будто в других языках такого не может быть.

Не помню по поводу wxWidgets, а Qt приводит свои контейнеры в соответствие плюсовым стандартным, так что обобщенные алгоритмы будут работать и на тех контейнерах, и на других. Просто надо писать обобщённый код, а не код для конкретного контейнера.


K>так и пусть разные будут, лишь бы можно было в итоге написать без шаблонов и обёрток метод вида:

K>
K>void process(collection<int>& items)
K>{
K>  for (auto& value: items)
K>  {
K>    ...
K>  }
K>}
K>

K>и передать туда и std::vector<int> и std::set<int> и QList<int> (при условии конечно, что все они унаследуются от collection<int>)

А в чем проблема писать с шаблонами?


K>Или всё же такое наследование и последующие виртуальные вызовы добавят увеличение потребления памяти, существенно снизит скорость работы и в плюсах так не принято?


Добавят. А существенно или нет — это зависит от задач, и объёмов данных. Не понимаю, зачем это в язык закладывать, а потом героически преодолевать, когда понадобится производительность? Не нравятся плюсы — пиши на шарпе, тебя кто-то заставляет?
Re[3]: Об эффективности виртуальных функций
От: пффф  
Дата: 05.08.24 14:26
Оценка:
Здравствуйте, andyp, Вы писали:

A>Как должен выглядеть такой обобщенный add для vector и set? Куда и что он втыкать будет — не понятно.


Ну, для set — это просто insert, для vector — это, скорее всего, push_back.

И хоть навставляйся хоть в set, хоть в vector через std::inserter
Re[6]: Об эффективности виртуальных функций
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 05.08.24 14:46
Оценка: :)
Здравствуйте, пффф, Вы писали:

П>Или плюсовики, которые уделяют внимание вопросам производительности.


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

Когда они делают на плюсах прикладной софт общего назначения, который работает заметно быстрее, чем у их коллег на Java/C#, у них может возникнуть ощущение, что они "уделяют внимание вопросам производительности", хотя на самом деле их спасают прежде всего готовые типовые оптимизации (семантика перемещения, RVO/NRVO, STL и прочее). Если они берутся за софт, в котором критична предельная для железа скорость, и даже несколько лишних обращений к памяти уже ощущаются, то могут возникать неприятные сюрпризы.
Re[4]: Об эффективности виртуальных функций
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 05.08.24 14:51
Оценка:
Здравствуйте, karbofos42, Вы писали:

K>Если мне не изменяет память, то разработчики STL максимально упарывались по производительности и потреблению памяти, чтобы работало и на утюгах.


Как раз на утюгах оно обычно работать не может. Это все-таки средства прикладного, а не системного программирования. Там нет предельной оптимизации — оно просто сделано так, чтобы работать в среднем лучше того же самого, вручную сделанного средним программистом.
Re[4]: Об эффективности виртуальных функций
От: andyp  
Дата: 05.08.24 14:52
Оценка:
Здравствуйте, пффф, Вы писали:

П>Ну, для set — это просто insert, для vector — это, скорее всего, push_back.

П>И хоть навставляйся хоть в set, хоть в vector через std::inserter

Инсертеры — тоже такая вещь, в которой не все прекрасно на мой взыскательный вкус . Этих итераторов для вставки три вида (back_insert_iterator, front_insert_iterator, insert_iterator), причем два из них по понятным причинам не будут работать с std::set. Параметром конструктора insert_iterator является итератор на позицию в контейнере для втыкания, который в случае std::set — просто хинт, а для последовательных контейнеров — нечто значимое.
Re[4]: Об эффективности виртуальных функций
От: andyp  
Дата: 05.08.24 14:55
Оценка:
Здравствуйте, пффф, Вы писали:

П>Ну, для set — это просто insert, для vector — это, скорее всего, push_back.


Дело не в том, что это будет технически, а в том что сам этот add имеет разный смысл для разных контейнеров. Вплоть до добавили "как-то куда-то". Я в самой такой абстракции мало смысла вижу
Re[4]: Об эффективности виртуальных функций
От: B0FEE664  
Дата: 05.08.24 15:00
Оценка:
Здравствуйте, karbofos42, Вы писали:

BFE>>Это потребует дополнительного расхода памяти размером в один указатель на объект, что противоречит известному принципу про платёж.

K>т.е. ТС не прав про гуманитариев, виртуальные методы создают большие накладные расходы и на них действительно имеет смысл экономить?
Евгений Музыченко пишет про скорость, а не про память.

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

BFE>>Впрочем, что мешает написать обёртку, которая будет принимать в конструкторе тип контейнера (или сам контейнер) и выставлять желаемый интерфейс? Такое можно написать за несколько часов без особого труда.

K>В итоге в проекте будет какой-то зоопарк, а накладных расходов ещё больше, чем было бы с виртуальными методами изначально.
Вот как напишете, такой зоопарк у вас и будет.

K>Хотя в плюсах наверно так принято, чтобы веселее было. Один интерфейс как в других языках — не интересно, а вот когда где-то vector, где-то QList или wxVector или ещё какой подобный класс — это весело и замечательно, особенно когда нужно из одного типа в другой данные гонять, т.к. у тебя есть vector, а нужный метод написан для QList.

Да, так принято и в этом нет ничего плохого.

BFE>>Однако, ICollection всё равно не получится сделать один на всех, ведь контейнеры шаблонные, а значит ICollection тоже будет шаблонным, т.е. ICollection<int> и ICollection<char> — это два разных типа.

K>так и пусть разные будут, лишь бы можно было в итоге написать без шаблонов и обёрток метод вида:
K>
K>void process(collection<int>& items)
K>{
K>  for (auto& value: items)
K>  {
K>    ...
K>  }
K>}
K>

K>и передать туда и std::vector<int> и std::set<int> и QList<int> (при условии конечно, что все они унаследуются от collection<int>)
Хмм... Есть у меня некоторые подозрения насчёт вашей квалификации...
Вот код:
void process(auto& items)
{
  for (auto& value: items)
  {
     std::cout << value << ' ';
  }
  std::cout << '\n';
}
//...
    std::vector<int> v;
    v.push_back(1);
    v.push_back(2);
    v.push_back(3);

    std::list<int> l;
    l.push_back(1);
    l.push_back(2);
    l.push_back(3);
    l.push_back(5);

    process(v);
    process(l);

Чем он вас не устраивает?
Зачем вам ICollection?

K>Или всё же такое наследование и последующие виртуальные вызовы добавят увеличение потребления памяти, существенно снизит скорость работы и в плюсах так не принято?

Что значит "принято"/"не принято"? C++ мультипарадигменный язык и стиль написания обычно зависит от квалификации программистов команды и их образования.
И каждый день — без права на ошибку...
Re[4]: Об эффективности виртуальных функций
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 05.08.24 15:05
Оценка:
Здравствуйте, karbofos42, Вы писали:

K>так и пусть разные будут, лишь бы можно было в итоге написать без шаблонов и обёрток метод вида


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

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

А если делать автоматические "подкапотные" средства, пусть и дающие малые накладные расходы для типовых прикладных задач, то при переходе к предельно нагруженным системам может оказаться, что накладные расходы стали слишком высоки, а избавиться от них невозможно, ибо они уже упрятаны под капот языка. И тогда остается или держать в языке аналогичные конструкции для низких уровней, или уходить на более низкоуровневый язык.
Re[7]: Об эффективности виртуальных функций
От: пффф  
Дата: 05.08.24 15:12
Оценка:
Здравствуйте, Евгений Музыченко, Вы писали:

П>>Или плюсовики, которые уделяют внимание вопросам производительности.


ЕМ>Среди профессиональных сишников преобладают те, кто пришел "снизу" — от железа и/или ассемблеров, ибо мало кто из чистых прикладников, привыкнув к современным ЯВУ, станет спускаться к C без крайней нужды.


Добрый десяток лет ковыряюсь с железом, так ни одного сишника и не увидел, одни плюсовики. В текущей конторе вообще по производительности сильно упарываются, и пишут всё на шаблонах, чтобы максимально всё оптимизировалось во время компиляции. И да, половина народу примерно лет 35ти возрастом. Это ещё не испорченные? Не слишком ли молоды для людей старой закалки?

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


ЕМ>Среди плюсовиков, пришедших в язык "сверху", изначально привыкших к "высокоуровневому" программированию, таких меньшинство.


Странно, у меня знакомый преподаёт в универе дисциплину что-то типа "Программирование микроконтроллеров", и делает это на плюсах


ЕМ>Система отбора, основанная на проверке знания стандартов, способствует тому, что человек умеет писать формально правильный код, но далеко не всегда видит, как именно по нему будет работать реальная машина.


Откуда ты знаешь про систему отбора?


ЕМ>Когда они делают на плюсах прикладной софт общего назначения, который работает заметно быстрее, чем у их коллег на Java/C#, у них может возникнуть ощущение, что они "уделяют внимание вопросам производительности", хотя на самом деле их спасают прежде всего готовые типовые оптимизации (семантика перемещения, RVO/NRVO, STL и прочее).


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


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


Такие сюрпризы любого могут ожидать
Re[5]: Об эффективности виртуальных функций
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 05.08.24 15:12
Оценка:
Здравствуйте, B0FEE664, Вы писали:

BFE>Что значит "принято"/"не принято"? C++ мультипарадигменный язык и стиль написания обычно зависит от квалификации программистов команды и их образования.


Тем не менее, оценки вроде "это не настоящий C++" можно встретить повсеместно.

Интересно, существуют подобные оценки для более других языков?
Re[5]: Об эффективности виртуальных функций
От: пффф  
Дата: 05.08.24 15:14
Оценка:
Здравствуйте, andyp, Вы писали:

П>>Ну, для set — это просто insert, для vector — это, скорее всего, push_back.

П>>И хоть навставляйся хоть в set, хоть в vector через std::inserter

A>Инсертеры — тоже такая вещь, в которой не все прекрасно на мой взыскательный вкус .


Что с ними не так?

A>Этих итераторов для вставки три вида (back_insert_iterator, front_insert_iterator, insert_iterator), причем два из них по понятным причинам не будут работать с std::set. Параметром конструктора insert_iterator является итератор на позицию в контейнере для втыкания, который в случае std::set — просто хинт, а для последовательных контейнеров — нечто значимое.


Я про inserter и говорю. Для вектора там надо end() передать, тогда будет класть в конец. Или begin(), если решишь, что add должен класть в начало. Весь остальной код останется без изменений
Re[6]: Об эффективности виртуальных функций
От: so5team https://stiffstream.com
Дата: 05.08.24 15:48
Оценка: +1
Здравствуйте, karbofos42, Вы писали:

S>>Вот и построили их на базе шаблонов.


K>И что мешает эти уже шаблонные классы коллекций унаследовать от таких же шаблонных общих базовых классов?


Когда у нас есть только шаблоны, то мы не платим ни за что больше. Только за шаблоны.

Добавить к шаблонам еще и виртуальные методы? Чтобы что?

Если кто-то хочет иметь фасад, за которым спрятаны реальные детали, то это делается легко и непринужденно и только там, где требуется.

И почему это приходится по несколько раз повторять? Неужели так сложно.
Re[8]: Об эффективности виртуальных функций
От: so5team https://stiffstream.com
Дата: 05.08.24 15:51
Оценка: :)
Здравствуйте, пффф, Вы писали:

ЕМ>>Система отбора, основанная на проверке знания стандартов, способствует тому, что человек умеет писать формально правильный код, но далеко не всегда видит, как именно по нему будет работать реальная машина.


П>Откуда ты знаешь про систему отбора?


Ну вы прям с козырей зашли. Только вот опыт показывает, что г-н Музыченко на конкретные вопросы не отвечает. Он гуманитарий, он не может в конкретику, проверенно неоднократно.
Re[5]: Об эффективности виртуальных функций
От: karbofos42 Россия  
Дата: 05.08.24 15:52
Оценка:
Здравствуйте, пффф, Вы писали:

П>Не будет


Будет

П>Компилятор соптимизирует


Что он соптимизирует? Мою обёртку для разных типов коллекций с виртуальными вызовами?

П>Наличие vector, QList или wxVector — это проблемы сторонних библиотек. Как будто в других языках такого не может быть.


В том же C# есть базовые интерфейсы IEnumerable, ICollection, IList и в 99% случаев людям достаточно стандартных реализаций, а кому нужны особые коллекции — там реализуются эти интерфейсы.
В C++ если у меня есть метод, принимающий std::vector, то я туда никак не передам QList.
Что строки в язык не завезли в своё время и получили в итоге зоопарк, что с коллекциями куча велосипедов.

П>Не помню по поводу wxWidgets, а Qt приводит свои контейнеры в соответствие плюсовым стандартным, так что обобщенные алгоритмы будут работать и на тех контейнерах, и на других. Просто надо писать обобщённый код, а не код для конкретного контейнера.


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

П>А в чем проблема писать с шаблонами?


Покажешь как на шаблонах реализовать метод: из исходной коллекции int чётные элементы положить в первую коллекцию, нечётные — во вторую?
На C# в лоб по-студенчески это как-то так:
void process(IEnumerable<int> source, ICollection<int> target1, ICollection<int> target2)
{
  foreach (var i in source)
  {
    if (i % 2 == 0) target1.Add(i)
    else target2.Add(i);
  }
}

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

П>Добавят. А существенно или нет — это зависит от задач, и объёмов данных.


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

П>Не понимаю, зачем это в язык закладывать, а потом героически преодолевать, когда понадобится производительность?


А STL — это уже часть языка? Кто бы меня заставил свою коллекцию написать без всей этой виртуальщины, если бы в STL написали иначе?

П>Не нравятся плюсы — пиши на шарпе, тебя кто-то заставляет?


Пишу
Re[8]: Об эффективности виртуальных функций
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 05.08.24 15:59
Оценка:
Здравствуйте, пффф, Вы писали:

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


Мы с Вами уже как-то обсуждали эту тему. Вы пришли в сферу МК уже на 32-разрядные модели, которые на один-два-три порядка по быстродействию, и на один-два порядка по объему памяти, превосходят типовые машины, на которых Страуструп с коллегами делали C++. Делать софт для таких МК можно посадить даже посредственного прикладника, умеющего использовать только то, что описано в стандарте (без внешних библиотек), и с большой вероятностью его софт будет решать ваши задачи.

А бОльшая часть софта для промышленных, реально массовых, 8- и 16-разрядных МК, таки написана на C. Для большинства моделей попросту нет плюсовых компиляторов, а которые есть, используют неохотно, ибо типичный убежденный сишник, как правило, уверен, что повышенные требования к ресурсам заложены в саму основу плюсов.

Вот сколько плюсовиков, работающих у вас с современными 32-разрядными МК, где сотни мегагерц и хотя бы сотни килобайт, смогут написать что-нибудь годное для 8-разрядного, где 5-10 МГц и единицы килобайт?

П>В текущей конторе вообще по производительности сильно упарываются


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

П>половина народу примерно лет 35ти возрастом. Это ещё не испорченные? Не слишком ли молоды для людей старой закалки?


При чем здесь возраст?

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


Для тех же 32-разрядных?

П>Откуда ты знаешь про систему отбора?


Из обсуждений собеседований на форумах.

П>C++ — отличный язык, раз позволяет не задумываться об оптимизации и тем не менее писать производительный код.


Не задумываться он позволяет только тогда, когда код пишется согласно разработанным правилам. А дайте писать без соблюдения правил, и тем, кто плохо понимает "кухню" — что останется от той производительности?
Re[5]: Об эффективности виртуальных функций
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 05.08.24 16:02
Оценка: :)
Здравствуйте, пффф, Вы писали:

П>Компилятор соптимизирует


Чем-то напоминает "им наверху виднее", "там разберутся" и подобное. Практика показывает, что ожидания оправдываются далеко не всегда.
Re[5]: Об эффективности виртуальных функций
От: karbofos42 Россия  
Дата: 05.08.24 16:06
Оценка:
Здравствуйте, B0FEE664, Вы писали:

BFE>Хмм... Есть у меня некоторые подозрения насчёт вашей квалификации...


Я забросил плюсы ещё до появления этой плюшки. Auto как параметр функции в C++20 завезли?

BFE>Чем он вас не устраивает?

BFE>Зачем вам ICollection?

С перебором вопрос снимается, т.к. там осилили единый интерфейс для итераторов и оказывается auto параметры в функции завезли, которые упрощают шаблоны.
С добавлением элементов можно так же изящно решить?
Re[6]: Об эффективности виртуальных функций
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 05.08.24 16:09
Оценка:
Здравствуйте, karbofos42, Вы писали:

K>Что строки в язык не завезли в своё время и получили в итоге зоопарк


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

В сам язык имело смысл изначально завезти кодирование строковых литералов в виде "длина+текст", наравне со стандартным нулем в конце, что в итоге сделали в C++11 для string.

K>А STL — это уже часть языка?


Многие считают, что да.
Re[7]: Об эффективности виртуальных функций
От: so5team https://stiffstream.com
Дата: 05.08.24 16:13
Оценка:
Здравствуйте, Евгений Музыченко, Вы писали:

ЕМ>В сам язык имело смысл изначально завезти кодирование строковых литералов в виде "длина+текст", наравне со стандартным нулем в конце, что в итоге сделали в C++11 для string.


Простите, что сделали в C++11?
Re[6]: Об эффективности виртуальных функций
От: пффф  
Дата: 05.08.24 16:17
Оценка: 2 (1)
Здравствуйте, karbofos42, Вы писали:

П>>Компилятор соптимизирует


K>Что он соптимизирует? Мою обёртку для разных типов коллекций с виртуальными вызовами?


Без виртуальных вызовов. С виртуальными, уверен, будет хуже


П>>Наличие vector, QList или wxVector — это проблемы сторонних библиотек. Как будто в других языках такого не может быть.


K>В том же C# есть базовые интерфейсы IEnumerable, ICollection, IList и в 99% случаев людям достаточно стандартных реализаций, а кому нужны особые коллекции — там реализуются эти интерфейсы.

K>В C++ если у меня есть метод, принимающий std::vector, то я туда никак не передам QList.
K>Что строки в язык не завезли в своё время и получили в итоге зоопарк, что с коллекциями куча велосипедов.

И что? Как твои хотелки изменят что-то в этой ситуации?


П>>Не помню по поводу wxWidgets, а Qt приводит свои контейнеры в соответствие плюсовым стандартным, так что обобщенные алгоритмы будут работать и на тех контейнерах, и на других. Просто надо писать обобщённый код, а не код для конкретного контейнера.


K>Что такое плюсовые стандартные?


Контейнеры? std::list, std::vector etc



П>>А в чем проблема писать с шаблонами?


K>Покажешь как на шаблонах реализовать метод: из исходной коллекции int чётные элементы положить в первую коллекцию, нечётные — во вторую?

K>На C# в лоб по-студенчески это как-то так:
K>
K>void process(IEnumerable<int> source, ICollection<int> target1, ICollection<int> target2)
K>{
K>  foreach (var i in source)
K>  {
K>    if (i % 2 == 0) target1.Add(i)
K>    else target2.Add(i);
K>  }
K>}
K>

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

#include <iterator>
#include <iostream>
#include <sstream>
#include <vector>
#include <list>
#include <set>


template< typename InputIteratorType
        , typename OutputIteratorType1
        , typename OutputIteratorType2
        , typename PredType
        >
void process(InputIteratorType b, InputIteratorType e, OutputIteratorType1 o1, OutputIteratorType2 o2, PredType pred)
{
    for(; b!=e; ++b)
    {
       if (pred(*b))
           *o1++ = *b;
       else
           *o2++ = *b;
    }
}

// Если прям хочется контейнер, то:
template< typename ContainerType
        , typename OutputIteratorType1
        , typename OutputIteratorType2
        , typename PredType
        >
void process(const ContainerType &c, OutputIteratorType1 o1, OutputIteratorType2 o2, PredType pred)
{
    for(const auto &v : c)
    {
       if (pred(v))
           *o1++ = v;
       else
           *o2++ = v;
    }
}

template<typename StreamType, typename ContainerType>
StreamType & printContainer(StreamType &s, const ContainerType &c)
{
    for(const auto &v : c)
        s << v << ", ";
    return s;
}

int main()
{
    std::vector<int> v = { 1, 2, 3, 4, 5, 6, 7, 8};
    std::set<int>  s;
    std::list<int> l;

    process( v, std::inserter(s, s.end()), std::inserter(l, l.end())
           , [](auto v) { return (v % 2 == 0); }
           );

    std::ostringstream oss;
    oss << "Vector: "; printContainer(oss, v) << "\n"; 
    oss << "Set   : "; printContainer(oss, s) << "\n"; 
    oss << "List  : "; printContainer(oss, l) << "\n"; 
 
    std::cout << oss.str();

    return 0;

}


Выдаёт
Vector: 1, 2, 3, 4, 5, 6, 7, 8, 
Set   : 2, 4, 6, 8, 
List  : 1, 3, 5, 7,




П>>Не нравятся плюсы — пиши на шарпе, тебя кто-то заставляет?


K>Пишу


Поздравляю
Re[7]: Об эффективности виртуальных функций
От: karbofos42 Россия  
Дата: 05.08.24 16:21
Оценка:
Здравствуйте, so5team, Вы писали:

S>Добавить к шаблонам еще и виртуальные методы? Чтобы что?


Чтобы было удобно и однообразно

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


Это работает в обе стороны. Можно было сделать коллекции как в Java или C#, а кому требуется максимально быстро — пусть берёт другую библиотеку или сам реализует.
Это же не часть языка и никто не заставляет именно STL использовать.

S>И почему это приходится по несколько раз повторять? Неужели так сложно.


Что повторять?
Перечитай первое сообщение в теме.
Я лишь привёл наглядный пример, что в С++ принято делать всрато своеобразно, но быстро, при этом экономя и на тех же виртуальных методах, на счёт которых у ТС вроде бы есть сомнения.
Re[6]: Об эффективности виртуальных функций
От: so5team https://stiffstream.com
Дата: 05.08.24 16:26
Оценка: 2 (1)
Здравствуйте, karbofos42, Вы писали:

K>Покажешь как на шаблонах реализовать метод: из исходной коллекции int чётные элементы положить в первую коллекцию, нечётные — во вторую?

K>На C# в лоб по-студенчески это как-то так:
K>
K>void process(IEnumerable<int> source, ICollection<int> target1, ICollection<int> target2)
K>{
K>  foreach (var i in source)
K>  {
K>    if (i % 2 == 0) target1.Add(i)
K>    else target2.Add(i);
K>  }
K>}
K>

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

Например, в рамках древнего уже C++11, вот так: https://wandbox.org/permlink/E7qO1tEgqeUVlQri
Re[6]: Об эффективности виртуальных функций
От: B0FEE664  
Дата: 05.08.24 16:28
Оценка:
Здравствуйте, karbofos42, Вы писали:

BFE>>Хмм... Есть у меня некоторые подозрения насчёт вашей квалификации...

K>Я забросил плюсы ещё до появления этой плюшки. Auto как параметр функции в C++20 завезли?

А причём тут auto?
Вот тот-же код в рамках С++98:

template<class T>
void ProcessItems(T itBegin, T itEnd)
{
  while(itBegin != itEnd)
  {
     std::cout << *itBegin++ << ' ';
  }
  std::cout << '\n';
} 


template<class T>
void Process(T& items)
{
    ProcessItems(items.begin(), items.end()); 
}


//...
    std::vector<int> v;
    v.push_back(1);
    v.push_back(2);
    v.push_back(3);

    std::list<int> l;
    l.push_back(1);
    l.push_back(2);
    l.push_back(3);
    l.push_back(5);

    process(v);
    process(l);


BFE>>Чем он вас не устраивает?

BFE>>Зачем вам ICollection?
K>С перебором вопрос снимается,
Т.е. интерфейс (как базовый класс) вам был не нужен? Да? А ничего , что это совершенно два разных подхода к решению задачи?

K>т.к. там осилили единый интерфейс для итераторов и оказывается auto параметры в функции завезли, которые упрощают шаблоны.

Поразительно, просто поразительно, какой я умный!

K>С добавлением элементов можно так же изящно решить?

Можно, но зачем?
И каждый день — без права на ошибку...
Re[8]: Об эффективности виртуальных функций
От: so5team https://stiffstream.com
Дата: 05.08.24 16:31
Оценка: +1
Здравствуйте, karbofos42, Вы писали:

S>>Добавить к шаблонам еще и виртуальные методы? Чтобы что?


K>Чтобы было удобно и однообразно


Если под "удобно" и "однообразно" вы понимаете только "удобно вам" и "однообразно для вас", то это одна история. Но, с большой долей вероятности, она про ваши половые трудности (пардон май френч). Т.к. в C++ начиная с середины 1990-х однообразно делается через итераторы, а не через интерфейсы коллекций.

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


K>Это работает в обе стороны. Можно было сделать коллекции как в Java или C#


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

K>Что повторять?


В C++ "не платят за то, что не используют".

K>Я лишь привёл наглядный пример, что в С++ принято делать всрато своеобразно, но быстро, при этом экономя и на тех же виртуальных методах


Не своеобразно, а естественным для C++ способом.

K>на счёт которых у ТС вроде бы есть сомнения.


ТС гуманитарий мнение которого по поводу С++ ничего не стоит.
Re[9]: Об эффективности виртуальных функций
От: пффф  
Дата: 05.08.24 16:32
Оценка:
Здравствуйте, Евгений Музыченко, Вы писали:

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


ЕМ>Мы с Вами уже как-то обсуждали эту тему. Вы пришли в сферу МК уже на 32-разрядные модели, которые на один-два-три порядка по быстродействию, и на один-два порядка по объему памяти, превосходят типовые машины, на которых Страуструп с коллегами делали C++. Делать софт для таких МК можно посадить даже посредственного прикладника, умеющего использовать только то, что описано в стандарте (без внешних библиотек), и с большой вероятностью его софт будет решать ваши задачи.


Или не будет. Задачи разные бывают. У нас тут и ЧПУ разные делают, например. Там и математика, и куча датчиков, например, расстояние до листа замерять, чтобы у лазера линзу фокусировать точнее. И куча подобного.


ЕМ>А бОльшая часть софта для промышленных, реально массовых, 8- и 16-разрядных МК, таки написана на C. Для большинства моделей попросту нет плюсовых компиляторов, а которые есть, используют неохотно, ибо типичный убежденный сишник, как правило, уверен, что повышенные требования к ресурсам заложены в саму основу плюсов.


Таки нет. Давайте примеры приводите, чтобы не быть балабоголословным.

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


ЕМ>Вот сколько плюсовиков, работающих у вас с современными 32-разрядными МК, где сотни мегагерц и хотя бы сотни килобайт, смогут написать что-нибудь годное для 8-разрядного, где 5-10 МГц и единицы килобайт?


Думаю, каждый первый. Надо будет — и на асме напишут.


П>>В текущей конторе вообще по производительности сильно упарываются


ЕМ>Насколько сильно? Уже отчетливо виден предел по возможностям железа, возможностей для дальнейшей оптимизации уже не просматривается, и другого выхода, как переходить на более мощное железо, не видит никто?


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


П>>половина народу примерно лет 35ти возрастом. Это ещё не испорченные? Не слишком ли молоды для людей старой закалки?


ЕМ>При чем здесь возраст?


Ну, по идее, эти люди уже должны быть испорчены современным образованием


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


ЕМ>Для тех же 32-разрядных?


Да.


П>>Откуда ты знаешь про систему отбора?


ЕМ>Из обсуждений собеседований на форумах.


А, ну тогда стопудово всё так и есть


П>>C++ — отличный язык, раз позволяет не задумываться об оптимизации и тем не менее писать производительный код.


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


Каким правилам? Надо просто знать язык, и представлять хоть немного, что получается из тез или иных конструкций
Re[6]: Об эффективности виртуальных функций
От: пффф  
Дата: 05.08.24 16:37
Оценка:
Здравствуйте, karbofos42, Вы писали:


K>И что мешает эти уже шаблонные классы коллекций унаследовать от таких же шаблонных общих базовых классов?


Можно. Но зачем? То же самое можно сделать и без всякой вирутальности. Я так понимаю, у тебя претензия к тому, что нет в стандартных контейнерах метода add, причем тут виртуальность, я не очень понял
Re[7]: Об эффективности виртуальных функций
От: karbofos42 Россия  
Дата: 05.08.24 16:41
Оценка:
Здравствуйте, пффф, Вы писали:

П>Выдаёт


т.е. сэкономили на вызове виртуального метода add, чтобы в итоге вот это всё с итераторами городить?
Это же и писать сомнительное удовольствие и вызывать и вообще тут есть выигрыш по скорости/памяти или в итоге и работать будет медленнее, чем дёрнуть виртуальный метод?
Re[8]: Об эффективности виртуальных функций
От: пффф  
Дата: 05.08.24 16:48
Оценка:
Здравствуйте, karbofos42, Вы писали:


K>т.е. сэкономили на вызове виртуального метода add,


Не понял, о какой экономии ты говоришь, и почем add должен быть обязательно виртуальным? Можешь это объяснить?


K>чтобы в итоге вот это всё с итераторами городить?


А в чем проблема?


K>Это же и писать сомнительное удовольствие и вызывать


В чем сомнительность?


K>и вообще тут есть выигрыш по скорости/памяти или в итоге и работать будет медленнее, чем дёрнуть виртуальный метод?


А с чего это будет работать медленнее?
Re[7]: Об эффективности виртуальных функций
От: karbofos42 Россия  
Дата: 05.08.24 16:58
Оценка:
Здравствуйте, B0FEE664, Вы писали:

BFE>Т.е. интерфейс (как базовый класс) вам был не нужен? Да? А ничего , что это совершенно два разных подхода к решению задачи?


Мне нужно удобство, информативность и всякие там контроли типов.
С интерфейсом это всё нагляднее, по заголовку метода понятно что туда нужно передавать, будут понятные сообщения об ошибках и т.п.
С auto я так понимаю придётся тупо комментарий развёрнутый писать что туда передавать, а при вызове ошибку получу не о том, что передал переменную неподходящего типа, а о том, что в шаблонном методе не нашлось у объекта метода begin().

BFE>Можно, но зачем?


Затем, что там методы на вставку элементов называются у контейнеров по-разному и auto с шаблонами не прокатят, придётся городить что-то на итераторах или ещё какие занимательные конструкции писать.
Re[9]: Об эффективности виртуальных функций
От: karbofos42 Россия  
Дата: 05.08.24 17:05
Оценка:
Здравствуйте, so5team, Вы писали:

S>Нельзя было, в C++ не было общего базового класса Object.

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

Так я привёл пример наследования шаблонного класса от шаблонного же абстрактного класса.
Технически никто не запрещает на C++ реализовать для коллекций интерфейсы по аналогии с C# или Java.
Под капотом понятно, что шаблоны и Generic — разные вещи и будут свои нюансы.
Так же как в C# и Java Generic по-разному реализованы и так же имеют свои особенности.
Re[8]: Об эффективности виртуальных функций
От: B0FEE664  
Дата: 05.08.24 17:06
Оценка:
Здравствуйте, so5team, Вы писали:

ЕМ>>Но удобство C++ как раз в том, что на нем можно писать всё.

S>Евгений, блин, уже лет 20 как пора забыть про эту чушь.

Почему? Разве есть что-то, что невозможно написать на C++?
И каждый день — без права на ошибку...
Re[8]: Об эффективности виртуальных функций
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 05.08.24 17:12
Оценка:
Здравствуйте, so5team, Вы писали:

S>Простите, что сделали в C++11?


Добавили пользовательские литералы. Правда, задачу создания таблиц строк вида "длина+текст" это все равно не решает, приходится извращаться, как и раньше.
Re[8]: Об эффективности виртуальных функций
От: B0FEE664  
Дата: 05.08.24 17:20
Оценка:
Здравствуйте, karbofos42, Вы писали:

BFE>>Т.е. интерфейс (как базовый класс) вам был не нужен? Да? А ничего , что это совершенно два разных подхода к решению задачи?

K>Мне нужно удобство, информативность и всякие там контроли типов.
Ну так возьмите vector и пользуйте.

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

Зачём вам что-то сложнее вектора?
И каждый день — без права на ошибку...
Re[9]: Об эффективности виртуальных функций
От: B0FEE664  
Дата: 05.08.24 17:27
Оценка:
Здравствуйте, Евгений Музыченко, Вы писали:

ЕМ>Добавили пользовательские литералы. Правда, задачу создания таблиц строк вида "длина+текст" это все равно не решает, приходится извращаться, как и раньше.


А string_view на что?
И каждый день — без права на ошибку...
Re[7]: Об эффективности виртуальных функций
От: karbofos42 Россия  
Дата: 05.08.24 17:31
Оценка:
Здравствуйте, пффф, Вы писали:

П>Можно. Но зачем? То же самое можно сделать и без всякой вирутальности. Я так понимаю, у тебя претензия к тому, что нет в стандартных контейнерах метода add, причем тут виртуальность, я не очень понял


В итоге приходим к тому, что в STL для контейнеров есть пара соглашений, типа методов begin() и end(), которые возвращают итераторы, благодаря которым в язык добавили "сахар" вида "for (auto &v : items)".
Есть подобное счастливое стечение обстоятельств, по которым метод size наверно везде одинаково называется и этим можно воспользоваться в шаблонах. Так себе решение, но ладно.
Для добавления такого не приключилось и потому тут мне набросали примеров с итераторами. Это и в плане кода объёмнее и я сомневаюсь, что будет быстрее работать, чем вызов виртуального метода, на котором сэкономили.
И вот теперь вопрос: опытные плюсовики в итоге у себя хардкодят конкретные контейнеры и не парятся о универсальности? Или заморачиваются и пишут эти все конструкции с итераторами?
Мне виртуальность не нужна как таковая. Просто коллекции в Java/C# за счёт общих интерфейсов мне видятся удобными.
В C++ же как-то с обратной стороны заходить нужно с добавлением элементов через итераторы, а не напрямую в коллекцию и непонятно что на выходе это даёт.
Re[10]: Об эффективности виртуальных функций
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 05.08.24 17:39
Оценка:
Здравствуйте, пффф, Вы писали:

П>Давайте примеры приводите


Чего именно примеры? В абзаце, после которого Вы это написали, минимум три разных утверждения.

П>В 8ми битный контроллер с килобайтом памяти нельзя запихнуть какую-то сложную задачу.


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

Чтобы оценить реальную потребность в объеме кода для решения задачи, очень полезно поглядывать на демки (intro) размером в один-четыре килобайта, которые вместе с видео еще и музыку играют. Понятно, что там полно хакерских приемов, но важен порядок размера. Мне приходилось писать на ассемблерах предельно компактный/быстрый код, чтобы уложиться в аппаратные рамки, но перед этими ребятами я всегда снимаю шляпу — сам так не умею. Когда кто-то категорически утверждает "эту задачу невозможно решить такими средствами", надо сразу отсылать туда.

П>Надо будет — и на асме напишут.


На асме как раз проще, там все под контролем.

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


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

П>по идее, эти люди уже должны быть испорчены современным образованием


Если "их учили", то да (таких большинство). Если "они учились", то все зависит от личности и способностей.

П>>>Откуда ты знаешь про систему отбора?


ЕМ>>Из обсуждений собеседований на форумах.


П>А, ну тогда стопудово всё так и есть


Ну а откуда мне ее еще знать?

П>Надо просто знать язык, и представлять хоть немного, что получается из тез или иных конструкций


Если в основе этого понимания лежит "компилятор соптимизирует" (а сейчас это типично), то лишь явная нужда может заставить этим интересоваться.
Re[9]: Об эффективности виртуальных функций
От: karbofos42 Россия  
Дата: 05.08.24 17:41
Оценка: :)
Здравствуйте, пффф, Вы писали:

П>Не понял, о какой экономии ты говоришь, и почем add должен быть обязательно виртуальным? Можешь это объяснить?


Да хоть size, хоть empty, хоть любой другой метод.
Если у коллекций есть общий тип с этими методами, то можно написать нормальный метод, в котором их вызывать.
Не делать так я вижу только одну причину: экономия на обращениях к таблице виртуальных методов и т.п.
Вдруг кто-то будет миллионы записей перемалывать в векторе, а тут вызов empty() будет виртуальный.
На шаблонах частично можно перекрыться, но это всё равно больше как костыль выглядит.

П>А в чем проблема?


Многословно и некрасиво же, больше шансов выстрелить в ногу.

П>А с чего это будет работать медленнее?


Вместо прямого обращения к коллекции идёт прослойка в виде итератора, который и создать нужно и его методы дёрнуть.
Re[10]: Об эффективности виртуальных функций
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 05.08.24 17:45
Оценка:
Здравствуйте, B0FEE664, Вы писали:

ЕМ>>задачу создания таблиц строк вида "длина+текст" это все равно не решает, приходится извращаться, как и раньше.


BFE>А string_view на что?


Так все равно ж исходные литералы лежат отдельно, с нулями в конце, а рядом лежат ссылки на них в объектах string_view.
Re[6]: Об эффективности виртуальных функций
От: B0FEE664  
Дата: 05.08.24 17:47
Оценка:
Здравствуйте, Евгений Музыченко, Вы писали:

BFE>>Что значит "принято"/"не принято"? C++ мультипарадигменный язык и стиль написания обычно зависит от квалификации программистов команды и их образования.

ЕМ>Тем не менее, оценки вроде "это не настоящий C++" можно встретить повсеместно.
Никто не использует настоящий С++ просто потому, что его никто не знает.

ЕМ>Интересно, существуют подобные оценки для более других языков?

Да. Например, JavaScript. На JavaScript можно написать код, который будет изменять сам себя. Даже теоретических наработок написания таких приложений мало, что уж говорить о практике. Мне, например, только однажды довелось написать функцию, которая в рантайме порождала функцию, которая в рантайме создавала функцию ответной реакции на событие. Вроде и ничего сложного, но преодолеть инертность мышления и заставить себя писать код в таком стиле очень трудно.
И каждый день — без права на ошибку...
Re[9]: Об эффективности виртуальных функций
От: karbofos42 Россия  
Дата: 05.08.24 17:50
Оценка: :)
Здравствуйте, B0FEE664, Вы писали:

BFE>Ну так возьмите vector и пользуйте.


Потом все вызовы придётся переписывать, если захочется поменять вектор на множество или какой другой контейнер.

BFE>Зачём вам что-то сложнее вектора?


По-моему контейнеры все достаточно простые и выбирают их под частые варианты использования через компромисс.
Re[10]: Об эффективности виртуальных функций
От: B0FEE664  
Дата: 05.08.24 18:04
Оценка: +2
Здравствуйте, karbofos42, Вы писали:

BFE>>Ну так возьмите vector и пользуйте.

K>Потом все вызовы придётся переписывать, если захочется поменять вектор на множество или какой другой контейнер.
Два-три раза перепишете, а потом, глядишь, и шаблоны освоите...

BFE>>Зачём вам что-то сложнее вектора?

K>По-моему контейнеры все достаточно простые
Простые. Ага. Покажешь коллеге константную ссылку на shared_ptr хранящий вектор shared_ptr'ов на объекты, так двумя руками креститься начинают.

K>и выбирают их под частые варианты использования через компромисс.

компромисс?
И каждый день — без права на ошибку...
Re[4]: Об эффективности виртуальных функций
От: B0FEE664  
Дата: 05.08.24 18:16
Оценка: +1
Здравствуйте, karbofos42, Вы писали:

K>Допустим, нужно сохранить коллекцию в json в виде массива [1,2,3] или что-то в этом духе.

K>Методу записи просто нужно перебрать все элементы коллекции, получить их значения и записать в json. Вектор там или множество — вообще же без разницы.
K>При чтении значений из json мне так же без разницы как там элементы хранятся, просто нужно их по очереди добавить в коллекцию.

Вы просто не понимаете, о чём пишите.
Если записать json ещё возможно (хотя не все это могут), то вот прочитать...
Не, не хочу снова писать про этот дрянной формат.
И каждый день — без права на ошибку...
Re[7]: Об эффективности виртуальных функций
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 05.08.24 18:28
Оценка:
Здравствуйте, B0FEE664, Вы писали:

BFE>Никто не использует настоящий С++ просто потому, что его никто не знает.


И его не существует?

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


Я когда-то так писал под Clipper (компилятор кода в стиле FoxPro под DOS, но допускал и интерпретацию кода, созданного в ходе выполнения). Когда встроенных средств параметризации не хватало, приходилось извращаться с созданием конструкций на ходу. Никаких приятных воспоминаний это не оставило. Сколько боролись с самомодификацией кода, чтоб снова к ней вернуться.
Re[8]: Об эффективности виртуальных функций
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 05.08.24 18:34
Оценка:
Здравствуйте, karbofos42, Вы писали:

K>привёл наглядный пример, что в С++ принято делать всрато своеобразно, но быстро


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

K>экономя и на тех же виртуальных методах, на счёт которых у ТС вроде бы есть сомнения.


Не, у ТС сомнений как раз никогда не было. Сомнения у тех, кто никогда не интересовался, как работает механизм виртуальных вызовов, но "где-то слышал, что он сильно снижает быстродействие".
Re[10]: Об эффективности виртуальных функций
От: пффф  
Дата: 05.08.24 19:39
Оценка:
Здравствуйте, karbofos42, Вы писали:


K>Да хоть size, хоть empty, хоть любой другой метод.

K>Если у коллекций есть общий тип с этими методами, то можно написать нормальный метод, в котором их вызывать.

А сейчас что мешает написать общий код?


K>Не делать так я вижу только одну причину: экономия на обращениях к таблице виртуальных методов и т.п.


Да, и это веская причина


K>Вдруг кто-то будет миллионы записей перемалывать в векторе, а тут вызов empty() будет виртуальный.


Да. А ты думаешь, что миллионы записей перемалывать — очень редкий кейс?
В текущей ситуации вызов size'а будет только один, если контейнер не меняется в ходе работы. В случае виртуального size оптимизатор скорее всего не сможет доказать, что size всегда возвращает одно и то же, и будет честно дёрuать виртуальный size на каждой итерации


K>На шаблонах частично можно перекрыться, но это всё равно больше как костыль выглядит.


Нормально выглядит. Я не понимаю, что ты докопался до плюсов? Иди в шарповый форум, раз на шарпе пишешь, не надо предлагать переделать плюсики в шарп


П>>А в чем проблема?


K>Многословно


Не проблема


K>и некрасиво же,


Вполне красиво


K>больше шансов выстрелить в ногу.


И где же?


П>>А с чего это будет работать медленнее?


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


Там всё непосредственно вызывается/передаётся, оптимизаторы сто лет назад уже такое схлопывают
Re[11]: Об эффективности виртуальных функций
От: пффф  
Дата: 05.08.24 19:55
Оценка:
Здравствуйте, Евгений Музыченко, Вы писали:

П>>Давайте примеры приводите


ЕМ>Чего именно примеры? В абзаце, после которого Вы это написали, минимум три разных утверждения.


Примеры "промышленных, реально массовых, 8- и 16-разрядных МК", на которых всё сейчас сделано, как вы утверждаете.
Отвечайте последовательно, не надо заглядывать в следующий абзац, не обработав предыдущий. Или у вас спекулятивное осмысление?

И что именно вам не нравится в трех разных утверждениях? Я вообще много разных утверждений пишу, гораздо больше трёх


П>>В 8ми битный контроллер с килобайтом памяти нельзя запихнуть какую-то сложную задачу.


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


Если есть десятки килобайт памяти программ, и килобайты ОЗУ — под это вполне можно писать на плюсах, и результат, скорее всего, будет компактнее и быстрее.


ЕМ>Чтобы оценить реальную потребность в объеме кода для решения задачи, очень полезно поглядывать на демки (intro) размером в один-четыре килобайта, которые вместе с видео еще и музыку играют. Понятно, что там полно хакерских приемов, но важен порядок размера. Мне приходилось писать на ассемблерах предельно компактный/быстрый код, чтобы уложиться в аппаратные рамки, но перед этими ребятами я всегда снимаю шляпу — сам так не умею. Когда кто-то категорически утверждает "эту задачу невозможно решить такими средствами", надо сразу отсылать туда.


Только не надо говорить, что все сишечники только такие.


П>>Надо будет — и на асме напишут.


ЕМ>На асме как раз проще, там все под контролем.


Только до-о-о-о-о-о-о-о-о-го


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


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


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


П>>по идее, эти люди уже должны быть испорчены современным образованием


ЕМ>Если "их учили", то да (таких большинство). Если "они учились", то все зависит от личности и способностей.


А, это не настоящие шотландцы, я понял


П>>>>Откуда ты знаешь про систему отбора?


ЕМ>>>Из обсуждений собеседований на форумах.


П>>А, ну тогда стопудово всё так и есть


ЕМ>Ну а откуда мне ее еще знать?


Так может, тогда не надо ничего категорично утверждать, не имея достоверных сведений о предмете?


П>>Надо просто знать язык, и представлять хоть немного, что получается из тез или иных конструкций


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


Приходится много кода писать. И да, обычно я использую разумные предположения, и считаю, что компилятор соптимизирует. Можно писать максимально оптимально, но тогда проект будет закончен через тысячу лет. Когда будет проблема с производительностью вылезать, тогда и будем разбираться. И проще запустить какой-нибудь профайлер, который покажет, где узкие места, чем писать всё "оптимально"
Re[2]: Об эффективности виртуальных функций
От: T4r4sB Россия  
Дата: 05.08.24 20:07
Оценка:
Здравствуйте, karbofos42, Вы писали:

K>Удобно ведь было бы в метод принимать просто коллекцию, получать какой-то абстрактный итератор для перебора или через виртуальный метод add добавить пару элементов.


Нет. Ну то есть задачи, где надо любую коллекцию принимать — это разве что перегонка в джсон какая-нибудь, ну там шаблончик один пишется и всё. В остальных случаях это не имеет никакого практического смысла. А накладные расходы на таскание указателя на ТВМ — очень серьёзные могут быть
Нет такой подлости и мерзости, на которую бы не пошёл gcc ради бессмысленных 5% скорости в никому не нужном синтетическом тесте
Re[8]: Об эффективности виртуальных функций
От: пффф  
Дата: 05.08.24 20:13
Оценка: +1
Здравствуйте, karbofos42, Вы писали:

П>>Можно. Но зачем? То же самое можно сделать и без всякой вирутальности. Я так понимаю, у тебя претензия к тому, что нет в стандартных контейнерах метода add, причем тут виртуальность, я не очень понял


K>В итоге приходим к тому, что в STL для контейнеров есть пара соглашений, типа методов begin() и end(), которые возвращают итераторы, благодаря которым в язык добавили "сахар" вида "for (auto &v : items)".

K>Есть подобное счастливое стечение обстоятельств, по которым метод size наверно везде одинаково называется и этим можно воспользоваться в шаблонах. Так себе решение, но ладно.

Это не счастливое стечение обстоятельств, это изначальный дизайн такой.

И из-за изначального дизайна нет и метода add у всех контейнеров, потому что он хз что должен делать. А некоторые контейнеры вообще не могут иметь некоторых методов. Вот чтобы делали методы push_front/push_back для стека или односвязанного списка? А ты предлагаешь, чтобы они были, как я понимаю, у god-объекта Object, от которого все наследуются. И что бы делали их реализации в наследниках? Ничего? Молча хавали данные и всё? Удачи в отладке. Или надо бросать исключение? Прощай, производительность. В C++ в общем-то всё тоже самое, только у него полиморфизм статический, и твоя программа просто не соберётся, и именно за это плюсики и любят.


K>Для добавления такого не приключилось и потому тут мне набросали примеров с итераторами. Это и в плане кода объёмнее и я сомневаюсь, что будет быстрее работать, чем вызов виртуального метода, на котором сэкономили.


Будет быстрее, будет


K>И вот теперь вопрос: опытные плюсовики в итоге у себя хардкодят конкретные контейнеры и не парятся о универсальности?


Когда как. Если что-то очень не устраивает по производительности — пишут свои контейнеры с заточкой под свои задачи. Это обычно удел контор типа Яндекса, или каких-нибудь САПРов. Остальным хватает стандартного, или из буста


K>Или заморачиваются и пишут эти все конструкции с итераторами?


Какая проблема с итераторами?


K>Мне виртуальность не нужна как таковая. Просто коллекции в Java/C# за счёт общих интерфейсов мне видятся удобными.


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


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


Не вижу проблем. Более того, такое не слишком нужно. Ну не могут алгоритмы одинаково хорошо работать со всеми типами контейнеров. У каждого контейнера свои преимущества и недостатки, и их надо выбирать, исходя из решаемых задач. А у вас, как я понимаю, дерьмово выходит с любыми контейнерами. Зато — удобно.


K>и непонятно что на выходе это даёт.


Производительность это даёт
Re[3]: Об эффективности виртуальных функций
От: Nuzhny Россия https://github.com/Nuzhny007
Дата: 05.08.24 20:14
Оценка:
Здравствуйте, Евгений Музыченко, Вы писали:

ЕМ>Они использовали хотя бы миллионы разных классов? Таблица-то общая на весь класс, а в каждом объекте добавляется только ее адрес.


Почему это? Восемь лишних байт на класс в каждом экземпляре.
Re[8]: Об эффективности виртуальных функций
От: T4r4sB Россия  
Дата: 05.08.24 20:20
Оценка:
Здравствуйте, karbofos42, Вы писали:

K>Для добавления такого не приключилось и потому тут мне набросали примеров с итераторами. Это и в плане кода объёмнее и я сомневаюсь, что будет быстрее работать, чем вызов виртуального метода, на котором сэкономили.


Почему сомневаешься? Не знаешь, как работает инлайн?
Нет такой подлости и мерзости, на которую бы не пошёл gcc ради бессмысленных 5% скорости в никому не нужном синтетическом тесте
Re[2]: Об эффективности виртуальных функций
От: Pauel Беларусь http://blogs.rsdn.org/ikemefula
Дата: 05.08.24 20:22
Оценка: 3 (1)
Здравствуйте, Stanislav V. Zudin, Вы писали:

SVZ>Предполагаю, что разница между прямым и косвенным вызовом функции происходит с тех времён.


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

Там обычно не просто косвенность, а пробег по таблицам vtbl для корректировки this если, скажем, наследование множественное.

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

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

Сейчас модно все вычисления выталкивать в компилятор, так что виртуальный вызов остается самым медленным
Re[10]: Об эффективности виртуальных функций
От: T4r4sB Россия  
Дата: 05.08.24 20:22
Оценка: +2
Здравствуйте, karbofos42, Вы писали:

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


Жесть
Нет такой подлости и мерзости, на которую бы не пошёл gcc ради бессмысленных 5% скорости в никому не нужном синтетическом тесте
Re[8]: Об эффективности виртуальных функций
От: T4r4sB Россия  
Дата: 05.08.24 20:27
Оценка: :)
Здравствуйте, karbofos42, Вы писали:

K>И вот теперь вопрос: опытные плюсовики в итоге у себя хардкодят конкретные контейнеры и не парятся о универсальности?


У меня появились сомнения что ты вообще программист.
Контейнер почти однозначно определяется сценарием использования.
Наприсмер, если мне нужно быстро искать элемент в коллекции, то прикинь, у меня будет контейнер поддерживающий поиск, у него по любому будет метод find, и в каком бреду мне понадобится универсальный интерфейс?
Нет такой подлости и мерзости, на которую бы не пошёл gcc ради бессмысленных 5% скорости в никому не нужном синтетическом тесте
Re[6]: Об эффективности виртуальных функций
От: andyp  
Дата: 05.08.24 20:52
Оценка:
Здравствуйте, пффф, Вы писали:

П>Я про inserter и говорю. Для вектора там надо end() передать, тогда будет класть в конец. Или begin(), если решишь, что add должен класть в начало. Весь остальной код останется без изменений


Можно даже reverse_iterator и begin(), тогда из вектора можно fifo замутить, вынимая из хвоста
Re[7]: Об эффективности виртуальных функций
От: пффф  
Дата: 05.08.24 20:54
Оценка: +1
Здравствуйте, andyp, Вы писали:

П>>Я про inserter и говорю. Для вектора там надо end() передать, тогда будет класть в конец. Или begin(), если решишь, что add должен класть в начало. Весь остальной код останется без изменений


A>Можно даже reverse_iterator и begin(), тогда из вектора можно fifo замутить, вынимая из хвоста


Да много чего можно интересного сделать. И главное, что никакой лишней платы в рантайме за это нет
Re[12]: Об эффективности виртуальных функций
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 05.08.24 20:55
Оценка:
Здравствуйте, пффф, Вы писали:

П>Примеры "промышленных, реально массовых, 8- и 16-разрядных МК", на которых всё сейчас сделано, как вы утверждаете.


Да их хренова гора разных. Из наиболее известных — PIC/AVR, менее известны Holtek, а уж клонов 8051 кто только не выпускал. Вот перечень.

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

П>И что именно вам не нравится в трех разных утверждениях? Я вообще много разных утверждений пишу, гораздо больше трёх


Я, если что, говорил о моих утверждениях, а не Ваших.

П>>>В 8ми битный контроллер с килобайтом памяти нельзя запихнуть какую-то сложную задачу.


П>Если есть десятки килобайт памяти программ, и килобайты ОЗУ — под это вполне можно писать на плюсах


Ну да, я знаю. Но большинство сишников, пишущих под такие контроллеры, и не знающих плюсов, в это не верит.

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


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

П>Только не надо говорить, что все сишечники только такие.


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

В конце 80-х, когда TC под DOS летал даже на XT, и давал очень приличный код, а TC++ заметно тормозил даже на AT286, и во ряде случаев давал код хуже, я сам был таким упертым. На BC++ в начале 90-х еще поглядывал с опаской, а потом попробовал VC++ под винду, и сразу перелез туда на плюсы.

ЕМ>>На асме как раз проще, там все под контролем.


П>Только до-о-о-о-о-о-о-о-о-го


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

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

П>У сишечника, кстати, уверен, будет всё гораздо хуже в подобном случае.

Если "хуже" — это "не так удобно, изящно и надежно" то да, а если "медленнее и/или объемнее", то нет.

П>Так может, тогда не надо ничего категорично утверждать, не имея достоверных сведений о предмете?


А где их взять, достоверные? Ну вот схожу я в десяток разных контор собеседоваться, выложу описание, и что помешает Вам заявить, что я был "не там" и беседовал "не с теми"? Какой материал есть, на том статистику и собираю.
Re[4]: Об эффективности виртуальных функций
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 05.08.24 20:58
Оценка:
Здравствуйте, Nuzhny, Вы писали:

N>Восемь лишних байт на класс в каждом экземпляре.


Если объектов единицы-десятки миллионов, и в каждом до десятков байт, то можно обойтись и 32-разрядными адресами, это будет по четыре байта. Если в объекте сорок байт, то четыре байта — 10%. Это считается много?
Re[3]: Об эффективности виртуальных функций
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 05.08.24 21:15
Оценка:
Здравствуйте, Pauel, Вы писали:

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


В разы могла быть разница только у самих команд вызова (прямой call по сравнению с загрузкой в регистр адреса vtbl, с последующим косвенным call). Если же сравнивать полную стоимость вызова (загрузку параметров, собственно вызов, создание стекового кадра, сохранение/восстановление регистров, возврат результата), то разница очень сильно уменьшается. Не следует забывать, что все стековые операции — косвенные.

P>Там обычно не просто косвенность, а пробег по таблицам vtbl для корректировки this если, скажем, наследование множественное.


Корректировка this выполняется при любом приведении указателя к производному типу. Сам вызов, что прямой, что виртуальный, выполняется на this конкретного объекта. Ну и множественное наследование — таки частный случай, а не общий.

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


Код генерится по сути такой же, как и раньше.

P>Такое будет заметно разумеется не на "тысячах вызовов" как пишет стартер


Про "тысячи" стартер писал в отношении всяких чисто системных косвенных вызовов, без привязки к C++. В отношении виртуальных функций стартер писал о "сотнях тысяч".

P>а когда количество вычислений в пересчете на операцию ничтожно


Не ничтожно, а хотя бы сравнимо.

P>Сейчас модно все вычисления выталкивать в компилятор


И как компилятор вычисляет то, что ему во время компиляции неизвестно?
Re[13]: Об эффективности виртуальных функций
От: пффф  
Дата: 05.08.24 22:08
Оценка:
Здравствуйте, Евгений Музыченко, Вы писали:

П>>Примеры "промышленных, реально массовых, 8- и 16-разрядных МК", на которых всё сейчас сделано, как вы утверждаете.


ЕМ>Да их хренова гора разных. Из наиболее известных — PIC/AVR, менее известны Holtek, а уж клонов 8051 кто только не выпускал. Вот перечень.


Я ждал, я ждал, что ты начнёшь про PIC и MSC-51 (AVR сам не трогал, не знаю, что за шляпа). Я тебе так скажу — те, кто под них пишет — конченные люди, их уже только могила исправит. И пишут они лютое говно.

Я знавал одного сишника/асмщика с PIC — на его код без слез смотреть было нельзя. Под MSC-51 сам писал. И много читал сишного кода. Тоже тоже очень хотелось плакать. Всё это было написано людьми, явно далекими от программирования, и ни о какой эффективности там говорить не приходилось.

MSC-51 вообще лютая штука. 16 бит адреса, и 128 байт оперативы, часть из которой — регистры проца, и стек. Мне ещё повезло — у меня был девайс с переключением страниц, туда до мегабайта этого кала можно было напихать.
Ни о каком промышленном серьёзном применении этого говна речи идти не может. Это уродцы, которые обычно выступают в роли вспомогательных чипов на больших чипах, для их настройки, и предназначено это для электронщиков, которые чутка освоили сишечку, и могут наговнякать управляющую программу для чипа, который они вкорячили в свою схему. Ну и код у всего этого именно такого качества. Конкретно я ковырял MSC-51, который был встроен в видеочип вроде от риалтека, и функционал MSC-51 там был для того, чтобы правильно настроить регистры видеочипа, которых там под тысячу, для различных режимов работы. Это нельзя называть серьёзным промышленным применением, ничего сложного там и не делается. И там нахрен не нужны ни высокие частоты, ни большие объёмы ОЗУ. Хотя, конечно, 128 байт у MSC-51 — это явный перебор, в смысле, недобор. Эти говноконтроллеры используются для возможности этакой кастомизации функционала основного чипа под свои применения. На самом деле, лучше бы, чтобы все уже выкинули это древнее говнецо на помоечку, и вкорячивали бы STMку какую, туда бы прошивали Lua, и для кастомизации нанимали бы студента-хипстера, чем издеваться над бедными электронщиками.

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

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

Я вам по секрету скажу — прошивки к этим устройствам пишут не какие-то супер-эффективные сишники-программисты, прошивки к ним пишут инженеры-электронщики, которые эти устройства ставят в свои схемы. "- Петров, ты схему развел? — Развёл. — Отлично. Петров, у вас же в институте язык C давали? — Давали, один семестр. — Отлично, Петров, вот ты прошивку и напишешь".


ЕМ>Они реально везде, где есть хоть какое-то "цифровое" поведение, но не требуется серьезных вычислений, обработки больших объемов данных и прочего. Осмотритесь внимательно вокруг — легко насчитаете десяток-другой таких устройств.


См выше. Я знаю об этом немного больше, изнутри, чем вы, витающие в своих фантазиях.


П>>Если есть десятки килобайт памяти программ, и килобайты ОЗУ — под это вполне можно писать на плюсах


ЕМ>Ну да, я знаю. Но большинство сишников, пишущих под такие контроллеры, и не знающих плюсов, в это не верит.


А вы много вообще сишников знаете, и ещё и пишущих под контроллеры? Нету таких сишников, как класса. Есть электронщики, осилившие немного сишечку, вот они и пишут эти говно-прошивки.


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


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


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


ЕМ>Просто писать будет удобнее, код будет более читаемым, ошибки делать сложнее, а вылавливать — легче.


Это вы про сишечку? Сериесли? Вы сами на сишечке много писали? Я, как минимум, написал один HTTP-сервер на сишечке, а что написали на сишечке вы?


П>>Только не надо говорить, что все сишечники только такие.


ЕМ>Я и не говорю. Но большинство сишников нынче упертые, потому они и не слезают с сей. Кроме, конечно, частных случаев, когда для платформы есть хороший сишный компилятор, а плюсового или нет, или он плохой.


Да, упёртые, как глав-пингвин. Это ничего не говорит об их уровне, как программистов, только лишь говорит об их узколобости.


ЕМ>В конце 80-х, когда TC под DOS летал даже на XT, и давал очень приличный код, а TC++ заметно тормозил даже на AT286, и во ряде случаев давал код хуже, я сам был таким упертым. На BC++ в начале 90-х еще поглядывал с опаской, а потом попробовал VC++ под винду, и сразу перелез туда на плюсы.


Что это должно доказать? Что сырой плюсовый компилятор 40 лет назад выдавал код хуже вылизанного сишного? А другие крмпиляторы пробовали? Например, Watcom? Первую версию для плюсов они вроде в 88ом выкатили. Году в 95ом это был самый крутой плюсовый компилятор


ЕМ>>>На асме как раз проще, там все под контролем.


П>>Только до-о-о-о-о-о-о-о-о-го


ЕМ>Да ладно. На хорошем макроассемблере, если наделать функций и макросов на все случаи жизни, можно вполне комфортно писать даже прикладной софт.


Можно. И даже возможно, как-то вполне комфортно. Но до-о-о-о-о-о-о-о-о-лго. Вы так говорите, как будто я на масме никогда ничего не писал. Я могу примерно прикинуть мою производительность на масме, и на плюсиках. Субъективно разница где-то от 1000 до 10000 раз


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

П>>У сишечника, кстати, уверен, будет всё гораздо хуже в подобном случае.

ЕМ>Если "хуже" — это "не так удобно, изящно и надежно" то да, а если "медленнее и/или объемнее", то нет.


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


П>>Так может, тогда не надо ничего категорично утверждать, не имея достоверных сведений о предмете?


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


Не понял, причем тут собеседования?

Ну и вы для начала сходите пособеседуйтесь, будет хоть какой-то фактический материал, а то насосут из пальца, и приходят тут кванторы всеобщности расставлять
Re[9]: Об эффективности виртуальных функций
От: karbofos42 Россия  
Дата: 06.08.24 04:01
Оценка: -1
Здравствуйте, Евгений Музыченко, Вы писали:

ЕМ>C++ тем и хорош, что на нем можно делать "своеобразно и очень быстро", так и "единообразно и менее быстро" (хотя иногда и столь же быстро, оптимизаторы насобачились). Если в него и добавлять еще более единообразные абстракции, то лишь сбоку, чтоб подключались только по запросу.


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

ЕМ>Не, у ТС сомнений как раз никогда не было. Сомнения у тех, кто никогда не интересовался, как работает механизм виртуальных вызовов, но "где-то слышал, что он сильно снижает быстродействие".


Так тут в итоге все пишут, что виртуальные функции медленные
Re[11]: Об эффективности виртуальных функций
От: karbofos42 Россия  
Дата: 06.08.24 04:24
Оценка: :)
Здравствуйте, пффф, Вы писали:

П>А сейчас что мешает написать общий код?


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

П>Да, и это веская причина


Ещё раз: я поэтому данный пример и привёл, ибо смотрим тему.

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


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

П>Нормально выглядит. Я не понимаю, что ты докопался до плюсов? Иди в шарповый форум, раз на шарпе пишешь, не надо предлагать переделать плюсики в шарп


Я не предлагаю ничего менять. Наглядно показываю как в плюсах ради экономии на тех же виртуальных вызовах пишут задом-наперёд и радуются.
Опять же смотрим название темы.
Re[9]: Об эффективности виртуальных функций
От: karbofos42 Россия  
Дата: 06.08.24 04:37
Оценка:
Здравствуйте, пффф, Вы писали:

П>Мне коллекции C++ за счет одинаковых интерфейсов тоже видятся удобными.


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

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


У меня то нормально всё получается. И когда кто-то выбирает неправильный контейнер или использование уже существующего меняется, то без проблем меняю тип контейнера и это не приводит к лавинообразным изменениям.
Ну, вот в жизни пишется как мне тут в теме несколько примеров с шаблонами привели?
Или всё же чаще хардкодится конкретный условный std::vector и методы все его принимают, т.к. нафиг надо шаблоны городить?
Re[9]: Об эффективности виртуальных функций
От: karbofos42 Россия  
Дата: 06.08.24 04:41
Оценка:
Здравствуйте, T4r4sB, Вы писали:

TB>Почему сомневаешься? Не знаешь, как работает инлайн?


Без бенчмарков не уверен, что оптимизатор всё это добро заинлайнит
Re: Об эффективности виртуальных функций
От: Zhendos  
Дата: 06.08.24 04:45
Оценка: +1
Здравствуйте, Евгений Музыченко, Вы писали:

ЕМ> Но почитал описании истории языка от Страуструпа (я читал несколько его книг, но истории раньше почему-то не попадалось), где он пишет, что многим программистам, в том числе системным, "было трудно поверить в то, что виртуальные функции могут быть достаточно быстрыми".


ЕМ>Откуда вообще могло взяться такое опасение в профессиональной-то среде? Ведь каждый системщик должен знать, что в любой ОС тьма косвенных вызовов


Всегда важно учитывать контекст. А каком компиляторе C++ тогда шла речь,
может о cfront, который просто в C преобразовывал?

Тогда даже банальное создание объекта на стеке
могло вызвать лишние виртуальные вызовы:

ClassWithVirtualDestructor obj;


Сейчас любой С++ компилятор вызовет для "auto" объекта конкретный деструктор,
и обойдется без всяких виртуальный вызовов,
мог ли тогда такую "оптимизацию" сделать cfront?

А сколько еще очевидных оптимизаций делает современный C++ компилятор
по сравнению с cfront?
Re[10]: Об эффективности виртуальных функций
От: so5team https://stiffstream.com
Дата: 06.08.24 04:49
Оценка: 2 (1)
Здравствуйте, karbofos42, Вы писали:

S>>Нельзя было, в C++ не было общего базового класса Object.

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

K>Так я привёл пример наследования шаблонного класса от шаблонного же абстрактного класса.


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

K>Технически никто не запрещает на C++ реализовать для коллекций интерфейсы по аналогии с C# или Java.


Тут нужно вспомнить еще пару вещей.

---

Во-первых, в C++ в шаблонах инстанциируются только те методы, которые используются. Т.е. если в конкретной реализации process у контейнера вызываются только begin/end, то генерироваться код будет только для begin/end и все. Что позволит мне для конкретной частной задачи сделать свой контейнер, у которого будут только begin/end и свой тип итератора (и то я могу в качестве итератора использовать голый указатель). И все. Такой мой урезанный контейнер уже будет пригоден для передачи process.

В случае наследования от условного collection<T> мне пришлось бы в своем урезанном контейнере кроме begin/end реализовывать еще и другие методы (size, empty и, может быть, еще что-то). Ну и нафига платить за то, что мне не нужно?

---

Во-вторых, в качестве output-итераторов в process могут быть переданы и не итераторы для контейнеров. Это могут быть итераторы, которые пишут значения в файл, в пайп или в COM-порт. И, благодаря самой концепции итераторов это возможно. А напиши мы process на ваших условных collection<T>, то кроме коллекций туда ничего нельзя было бы передать. И если бы нам потребовалось сохранять результат фильтрации в пайп, то это была бы уже другая функция process.

Причем, замечу, за счет шаблонов мы вообще не имеем никаких накладных расходов, даже если мы оборачиваем в output-итератор объект для работы с COM-портом.

===

Ну и пару слов по поводу того, что в C++ шаблоны базируются на утиной типизации здорового человека (т.е. проверки на наличие нужных методов делаются в compile-time). Главную проблему этой утиной типизации в C++ уже победили в C++20 за счет концептов, которые могут проверить гораздо более формально специфицированный "контракт". Чего не было в C++98 и что вело к простыням ошибок, если у какого-то параметра шаблона не оказывалось нужного метода.

Вот так выглядит пример, который вы хотели видеть, в рамках C++20 с концептами: https://wandbox.org/permlink/Plv2rFZlwbFFgQ1i
Обратите внимание на третий случай -- там в качестве output-итераторов отнюдь не контейнеры. И все равно это работает для process-а.
Re[9]: Об эффективности виртуальных функций
От: so5team https://stiffstream.com
Дата: 06.08.24 04:51
Оценка: +1 :)
Здравствуйте, B0FEE664, Вы писали:

ЕМ>>>Но удобство C++ как раз в том, что на нем можно писать всё.

S>>Евгений, блин, уже лет 20 как пора забыть про эту чушь.

BFE>Почему?


Экономическая целесообразность.

BFE>Разве есть что-то, что невозможно написать на C++?


Я бы хотел посмотреть на C++ный вариант, скажем, ActiveRecord из Ruby-On-Rails.
Отредактировано 06.08.2024 5:00 so5team . Предыдущая версия .
Re[9]: Об эффективности виртуальных функций
От: so5team https://stiffstream.com
Дата: 06.08.24 04:56
Оценка: :)
Здравствуйте, Евгений Музыченко, Вы писали:

S>>Простите, что сделали в C++11?


ЕМ>Добавили пользовательские литералы. Правда, задачу создания таблиц строк вида "длина+текст" это все равно не решает, приходится извращаться, как и раньше.


Теперь смотрим на вашу исходную фразу:

В сам язык имело смысл изначально завезти кодирование строковых литералов в виде "длина+текст", наравне со стандартным нулем в конце, что в итоге сделали в C++11 для string.


Т.е. вы сперва утверждаете, что кодирование в виде "длина+текст" буквально "в итоге сделали в C++11 для string", а затем, следом, говорите, что "задачу создания таблиц строк вида "длина+текст" это все равно не решает"

Евгений, а вы не просто гуманитарий, а гуманитарий с признаками шизофренического расстройства.
Re[10]: Об эффективности виртуальных функций
От: so5team https://stiffstream.com
Дата: 06.08.24 04:58
Оценка:
Здравствуйте, karbofos42, Вы писали:

K>Так тут в итоге все пишут, что виртуальные функции медленные


Кто это пишет? Я здесь пока не увидел ни одного бенчмарка.

Хотя как раз ТС должен был бы начать тему с того, что "вот я провел такие-то замеры и они показывают вот такую-то разницу между обычными и виртуальными вызовами, разница настолько мала, что ей можно пренебречь".
Re[11]: Об эффективности виртуальных функций
От: karbofos42 Россия  
Дата: 06.08.24 05:01
Оценка:
Здравствуйте, so5team, Вы писали:

S>Вот так выглядит пример, который вы хотели видеть, в рамках C++20 с концептами: https://wandbox.org/permlink/Plv2rFZlwbFFgQ1i


Немного поправил создание объектов:
std::array<int, 5> source{ 5, 4, 3, 2, 1 };
std::set<float> to_1;
std::vector<bool> to_2;

Успешно выполнилось, просто результат несколько изменился. Пожалуй, это не то, чего я хотел от типизированного языка с проверкой compile-time
Re[11]: Об эффективности виртуальных функций
От: karbofos42 Россия  
Дата: 06.08.24 05:05
Оценка: -1
Здравствуйте, so5team, Вы писали:

S>Кто это пишет? Я здесь пока не увидел ни одного бенчмарка.


Так меня все убеждают, что виртуальные методы в коллекциях сделают их медленными и такое не нужно, а то миллионы записей перелопачиваться перестанут.
Re[12]: Об эффективности виртуальных функций
От: so5team https://stiffstream.com
Дата: 06.08.24 05:08
Оценка: 2 (1)
Здравствуйте, karbofos42, Вы писали:

S>>Вот так выглядит пример, который вы хотели видеть, в рамках C++20 с концептами: https://wandbox.org/permlink/Plv2rFZlwbFFgQ1i


K>Немного поправил создание объектов:

K>
K>std::array<int, 5> source{ 5, 4, 3, 2, 1 };
K>std::set<float> to_1;
K>std::vector<bool> to_2;
K>

K>Успешно выполнилось, просто результат несколько изменился. Пожалуй, это не то, чего я хотел от типизированного языка с проверкой compile-time

За это нужно говорить спасибо совместимости с Си. Без которой, следует признать, востребованность C++ даже в наши дни была бы ниже (полагаю в разы, если не на порядок).

Когда это является проблемой можно использовать strong typedef-ы (хоть в виде готовых библиотек, хоть слепленные на коленке). Благо все это будет с нулевыми накладными расходами в run-time. Хотя ТС может и прифигеть от использования возможностей современного C++ в этих самых strong typedef-ах.
Re[12]: Об эффективности виртуальных функций
От: so5team https://stiffstream.com
Дата: 06.08.24 05:10
Оценка:
Здравствуйте, karbofos42, Вы писали:

S>>Кто это пишет? Я здесь пока не увидел ни одного бенчмарка.


K>Так меня все убеждают


Поосторожнее с категориями всеобщности. Я, например, вас ни в чем подобном не утверждал.

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


Вынужден повторить: тут нет пока бенчмарков, поэтому, по сути, и предмета разговора нет.
У меня было желание набросать такой, что-то вроде перемножения матриц, реализованных разными способами. Но нет времени чтобы этим заняться.
Re[13]: Об эффективности виртуальных функций
От: karbofos42 Россия  
Дата: 06.08.24 05:48
Оценка: :)
Здравствуйте, so5team, Вы писали:

S>Поосторожнее с категориями всеобщности. Я, например, вас ни в чем подобном не утверждал.


ОК.

S>Вынужден повторить: тут нет пока бенчмарков, поэтому, по сути, и предмета разговора нет.

S>У меня было желание набросать такой, что-то вроде перемножения матриц, реализованных разными способами. Но нет времени чтобы этим заняться.

Для виртуальных методов бенчмарки сложно придумать и сделать.
Я набросил на вентилятор относительно простой в реализации вариант с коллекциями, но как-то не оценили в большинстве своём и смысла в таком бенчмарке не будет.
Сложность в том, что отказ от виртуальных функций влечёт за собой изменения в архитектуре.
Где-то наследование на композицию заменится, где-то через шаблонную обёртку решится и т.д.
По сути уже будет сравнение двух подходов и там начнутся споры, что примеры неправильные и не то показывают.
Вот чел написал тесты сравнения просто вызовов виртуальных функций:
https://stackoverflow.com/a/77983092
Сами по себе виртуальные вызовы сильно медленнее и вроде ужасно.
Но вот что будет суммарно с кодом, когда в нём появятся всякие обёртки для "эмуляции" виртуальности — вопрос.
Может оптимизатор всё съест, заинлайнит и получится в итоге со всех сторон без виртуальных функций лучше, а может разница не такая большая в итоге будет и можно не загоняться.
Re[5]: Об эффективности виртуальных функций
От: cserg  
Дата: 06.08.24 06:24
Оценка:
Здравствуйте, Евгений Музыченко, Вы писали:

N>>Восемь лишних байт на класс в каждом экземпляре.

ЕМ>Если объектов единицы-десятки миллионов, и в каждом до десятков байт, то можно обойтись и 32-разрядными адресами,
Не можно. Надо же не объекты считать, а где загрузчик разместит виртуальную таблицу в памяти. Где гарантия в 64 битной системе, что она будет находиться в пределах 32 битного адреса?
Re[4]: Об эффективности виртуальных функций
От: Pauel Беларусь http://blogs.rsdn.org/ikemefula
Дата: 06.08.24 06:36
Оценка:
Здравствуйте, Евгений Музыченко, Вы писали:

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


ЕМ>В разы могла быть разница только у самих команд вызова (прямой call по сравнению с загрузкой в регистр адреса vtbl, с последующим косвенным call). Если же сравнивать полную стоимость вызова (загрузку параметров, собственно вызов, создание стекового кадра, сохранение/восстановление регистров, возврат результата), то разница очень сильно уменьшается. Не следует забывать, что все стековые операции — косвенные.


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

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


не совсем понятно, что там корректировать при отсутствии множественного наследования? this по идее один и тот же, т.к. vtbl ровно одна штука. Может я забыл чего, последний раз году в 15м это смотрел.

ЕМ>Про "тысячи" стартер писал в отношении всяких чисто системных косвенных вызовов, без привязки к C++. В отношении виртуальных функций стартер писал о "сотнях тысяч".


Сотни тысяч это всё равно не тот масштаб

P>>Сейчас модно все вычисления выталкивать в компилятор


ЕМ>И как компилятор вычисляет то, что ему во время компиляции неизвестно?


Никак. Это человек пишет код нужным образом.
Re[10]: Об эффективности виртуальных функций
От: T4r4sB Россия  
Дата: 06.08.24 06:55
Оценка:
Здравствуйте, karbofos42, Вы писали:

K>Или всё же чаще хардкодится конкретный условный std::vector и методы все его принимают, т.к. нафиг надо шаблоны городить?


Во-первых, мегауниверсальный метод нужен редко, и тогда принимают пару итераторов.
Во-вторых, в реальном методе реального проекта ты знаешь с каким классом работаешь.
Нет такой подлости и мерзости, на которую бы не пошёл gcc ради бессмысленных 5% скорости в никому не нужном синтетическом тесте
Re[10]: Об эффективности виртуальных функций
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 06.08.24 06:57
Оценка:
Здравствуйте, karbofos42, Вы писали:

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


Почему непременно в библиотеках? Нужные средства могут быть и в ядре языка. В плюсах, как в свое время и с C, выбрали в целом правильный подход, ограничив ядро до минимума, и вынеся все остальное в библиотеку, чтобы сделать их "ортогональными". Но если в C ядро в целом достаточно функционально, и библиотека естественным образом расширяет его возможности, то в плюсовом ядре долгое время не было критически необходимых средств, да и сейчас есть не все, из-за чего библиотека вынуждена не только расширять возможности языка, но и преодолевать недостатки его ядра. Той самой "ортогональности" в плюсах нет, и еще долго не будет. Отсюда и большинство велосипедов.

K>Так тут в итоге все пишут, что виртуальные функции медленные


Вам пишут вовсе не это. Медленны не сами по себе виртуальные функции, а решения, к которым Вы эти функции предлагаете прибить гвоздями. Если предложите решения, в которых виртуальные функции используются только при необходимости, а без нее обходятся дешевыми средствами, то будет смысл обсуждать. С идеей строить на них любой контейнер я тоже не согласен категорически, хотя сам знаю, что ничего особо тяжелого в них нет. Но мне регулярно требуются решения, в которых нет ничего лишнего, а Ваш подход предполагает лишить меня такой возможности, дав взамен лишь сомнительное преимущество в синтаксисе.
Re[2]: Об эффективности виртуальных функций
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 06.08.24 06:58
Оценка:
Здравствуйте, Zhendos, Вы писали:

Z>Всегда важно учитывать контекст. А каком компиляторе C++ тогда шла речь,


В том-то и дело, что во всех виденных утверждениях о якобы медленности виртуальных функций я еще ни разу не встречал контекста.
Re[10]: Об эффективности виртуальных функций
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 06.08.24 07:02
Оценка:
Здравствуйте, so5team, Вы писали:

S>Т.е. вы сперва утверждаете, что кодирование в виде "длина+текст" буквально "в итоге сделали в C++11 для string"


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

S>следом, говорите, что "задачу создания таблиц строк вида "длина+текст" это все равно не решает"


Именно так — не решает. Один костыль поменяли на другой, как обычно.
Re[6]: Об эффективности виртуальных функций
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 06.08.24 07:03
Оценка:
Здравствуйте, cserg, Вы писали:

C>Надо же не объекты считать, а где загрузчик разместит виртуальную таблицу в памяти. Где гарантия в 64 битной системе, что она будет находиться в пределах 32 битного адреса?


Ниасилил. Можно расшифровать подробнее?
Re[11]: Об эффективности виртуальных функций
От: so5team https://stiffstream.com
Дата: 06.08.24 07:14
Оценка:
Здравствуйте, Евгений Музыченко, Вы писали:

S>>Т.е. вы сперва утверждаете, что кодирование в виде "длина+текст" буквально "в итоге сделали в C++11 для string"


ЕМ>Да, сделали — компилятор передает конструктору длину строки в готовом виде, а не заставляет вычислять ее во время выполнения или ожидать, что это сделает оптимизатор.


К кодированию строки в виде "длина+текст" это не имеет отношения.
Для тех, кто хотел иметь такую же оптимизацию в C++98 можно было использовать что-то вроде:
#include <iostream>
#include <string>

template<std::size_t N>
std::size_t literal_len(const char (&)[N]) { return (N-1); }

#define STR_LITERAL_TO_STRING(literal) std::string((literal), literal_len(literal))

int main()
{
    std::string my_string = STR_LITERAL_TO_STRING("Hello, World");

    std::cout << "size: " << my_string.size() << ", value: '" << my_string << "'" << std::endl;
}

Цинк: https://wandbox.org/permlink/MisGyCklfxaat6wI
Re[5]: Об эффективности виртуальных функций
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 06.08.24 07:20
Оценка:
Здравствуйте, Pauel, Вы писали:

P>не совсем понятно, что там корректировать при отсутствии множественного наследования? this по идее один и тот же


Да, я забыл, что в этом случае смещения не корректируются.

P>Сотни тысяч это всё равно не тот масштаб


Исходя из чего?
Re[11]: Об эффективности виртуальных функций
От: karbofos42 Россия  
Дата: 06.08.24 07:38
Оценка: :))
Здравствуйте, T4r4sB, Вы писали:

TB>Во-первых, мегауниверсальный метод нужен редко, и тогда принимают пару итераторов.


Никогда не бывает такого, что ошиблись с выбором контейнера или объём/характер данных несколько изменился, что требуется вектор заменить на хэш-таблицу с быстрым поиском?
У меня вот периодически встречаются задачи, когда кто-то когда-то написал на аналоге вектора, т.к. и данных мало и вызывалась функция редко. Спустя годы в коллекцию и информации куда больше попадает и уже чуть ли не на hit test мыши привязывается, что нужно оптимизировать, уходить от полного перебора коллекции для поиска элементов и т.п.
Сидеть менять везде std::vector на std::unordered_set, а в итоге окажется, что вроде по скорости нормально выходит, но по памяти фигня, стоит попробовать что-то ещё. И опять сидеть всякие хелперы править, которым по сути плевать на тип коллекции?
Вопрос не в написании кода, а в его поддержке и развитии.

TB>Во-вторых, в реальном методе реального проекта ты знаешь с каким классом работаешь.


В реальном методе реального проекта я работаю с тем, что дали.
Если мне нужно найти элемент в коллекции и эта коллекция — вектор, то придётся искать перебором.
Не буду же я ради одной побочной функции лезть и переписывать половину программы, просаживая другие более важные функции.
В C# я буду использовать виртуальный метод коллекции Contains, который скажет есть ли нужный объект в коллекции.
Для List(аналог вектора) он будет работать через перебор, для хэш-множества — с быстрым поиском по хэшу.
Если я заменю тип коллекции с List на HashSet, то у меня автоматически этот самый вызов Contains станет работать быстрее с использованием плюшек множества.
В C++ я так понимаю будет вот такая ситуация:
https://stackoverflow.com/a/71063103
Сначала напишешь для вектора через std::find, а потом при переходе на множество упустишь момент и в нём всё продолжит искаться перебором, без использования плюшек нового контейнера.
Re[7]: Об эффективности виртуальных функций
От: cserg  
Дата: 06.08.24 07:50
Оценка:
Здравствуйте, Евгений Музыченко, Вы писали:

ЕМ>Ниасилил. Можно расшифровать подробнее?

Объект содержит указатель на таблицу виртуальных функций. Таблица в памяти находится там, где ее разместил загрузчик исполняемого файла/разделяемой библиотеки. Загрузчик в 64 битной системе не обязан размещать ее в пределах 32 битного адреса, т.е. не хватит 32 бит для такого указателя.
Re[11]: Об эффективности виртуальных функций
От: karbofos42 Россия  
Дата: 06.08.24 07:54
Оценка: :)
Здравствуйте, Евгений Музыченко, Вы писали:

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


Я пишу о том, что в других языках с другими приоритетами в стандартных библиотеках коллекций используются виртуальные методы и люди не жужжат.
Кому нужно что-то супер-мега оптимизированное и без лишнего — всегда можно взять или сделать стороннюю библиотеку и не прикручивать виртуализацию.
Вариант коллекций из C#/Java мне видится более удобный и безопасный в повседневном использовании, где никто байты не считает и миллионами записей не орудует.
Зато стандартность таких коллекций и их интерфейсов приводит к простоте написания кода рядовыми разработчиками и сложнее им выстрелить себе в ногу.
Против STL ничего не имею, но ведь варианты на всех этих шаблонах в итоге дают простые способы выстрелить себе в ногу.
Вроде язык с контролем типов и максимально проверки вынесены в compile-time, а вроде в коллекцию bool легко int запишет с неявным преобразованием и лови баг сиди.
Ну, а раз в языке так принято и народу так нравится, значит тут так принято и те же виртуальные методы для плюсовиков действительно достаточно дороги для использования и целесообразно на них экономить
Re[14]: Об эффективности виртуальных функций
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 06.08.24 08:12
Оценка:
Здравствуйте, пффф, Вы писали:

П>те, кто под них пишет — конченные люди, их уже только могила исправит. И пишут они лютое говно.


Вот прям все, без исключения? А почему, собственно? Что, по-Вашему, делает их такими?

П>Я знавал одного сишника/асмщика с PIC — на его код без слез смотреть было нельзя. Под MSC-51 сам писал. И много читал сишного кода. Тоже тоже очень хотелось плакать. Всё это было написано людьми, явно далекими от программирования, и ни о какой эффективности там говорить не приходилось.


А я видел немало кода, написанного вроде бы профессиональными программистами, но тоже хотелось плакать. Какой вывод-то?

П>Ни о каком промышленном серьёзном применении этого говна речи идти не может.


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

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


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

П>Ну и код у всего этого именно такого качества.


Именно из-за устройства МК? Какие параметры МК обрекают любой код для него на говнистость?

П>Это нельзя называть серьёзным промышленным применением, ничего сложного там и не делается.


А если этого выпускается тонны, и продается на миллиарды?

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


Да, и в каждые настольные часы вкорячить линукс. А кто за все это заплатит? STM-ки вроде как не бесплатные.

П>Другое применение этих уродцев — это контроллеры стиральных машин


Которые выпускаются штучно, отчего встречаются очень редко.

П>где оно решает мега сложные задачи по измерению температуры воды и её нагреву (там аж ПИД-регулятор надо делать, это да), да по смене режимов работы, включения мотора барабана и насосов на двухчасовом цикле стирки. Да, тут 5 Мгц частоты точно мало, тут 160 надо.


Про оценку распределения масс в барабане по соотношению токов в обмотках двигателя Вы явно не в курсе.

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


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

П>но квалификации тут не нужно никакой от слова вообще.


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

П>прошивки к этим устройствам пишут не какие-то супер-эффективные сишники-программисты, прошивки к ним пишут инженеры-электронщики


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

П>Петров, у вас же в институте язык C давали? — Давали, один семестр. — Отлично, Петров, вот ты прошивку и напишешь".


И что, если бы Петрову давали не C, а C++ или Pascal, он написал бы хуже?

П>А вы много вообще сишников знаете, и ещё и пишущих под контроллеры? Нету таких сишников, как класса.


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

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


Каким образом все эти качества могут концентрироваться в плюсовом компиляторе, но избегать попадания в сишный? Если в компиляторе есть соответствующая логика — он будет оптимизировать до упора, если ее нет — будет делать код, как придется. Стандарты C++ не устанавливают конкретных требований к оптимизации, за исключением некоторых явно оговоренных. А многие компиляторы изначально умеют и C, и C++. Функционально эквивалентные исходники они чаще всего компилируют в один и тот же код.

ЕМ>>Просто писать будет удобнее, код будет более читаемым, ошибки делать сложнее, а вылавливать — легче.


П>Это вы про сишечку?


Это я про плюсики по сравнению с сишечкой.

П>Вы сами на сишечке много писали?


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

П>Я, как минимум, написал один HTTP-сервер на сишечке


Это считается сложным проектом для C? Не знал, честно. Вот, например, Simple HTTP Server — цельных 25 килобайт исходник. Или Ваш был сильно круче?

П>что написали на сишечке вы?


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

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

П>Что это должно доказать? Что сырой плюсовый компилятор 40 лет назад выдавал код хуже вылизанного сишного?


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

П>А другие крмпиляторы пробовали? Например, Watcom?


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

П>Я могу примерно прикинуть мою производительность на масме, и на плюсиках. Субъективно разница где-то от 1000 до 10000 раз


Как-то слишком разительно. Ну, или для Вас ассемблеры просто сильно непривычны.

П>Код среднего плюсовика всегда выиграет у кода среднего сишечника по скорости.


Да не выиграет он всегда. Если и тот, и другой делают код согласно устоявшимся правилам и рекомендациям, то где-то будет быстрее на C за счет простоты, где-то — на плюсах за счет выразительности. А если как попало, то и там, и там будет медленно.
Re[12]: Об эффективности виртуальных функций
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 06.08.24 08:19
Оценка:
Здравствуйте, so5team, Вы писали:

S>Для тех, кто хотел иметь такую же оптимизацию в C++98 можно было использовать что-то вроде:


Осталось найти способ сложить строки в таблицу, о чем я с самого начала и говорил. Когда нужно просто вывести конкретную строку, уже не особо важно, известна ее длина заранее, или нет.
Re[8]: Об эффективности виртуальных функций
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 06.08.24 08:23
Оценка:
Здравствуйте, cserg, Вы писали:

C>Объект содержит указатель на таблицу виртуальных функций. Таблица в памяти находится там, где ее разместил загрузчик исполняемого файла/разделяемой библиотеки. Загрузчик в 64 битной системе не обязан размещать ее в пределах 32 битного адреса, т.е. не хватит 32 бит для такого указателя.


Я имел в виду 32-разрядное приложение, а не ограничение адреса в 64-разрядной системе.
Re[13]: Об эффективности виртуальных функций
От: so5team https://stiffstream.com
Дата: 06.08.24 08:29
Оценка: :)
Здравствуйте, Евгений Музыченко, Вы писали:

ЕМ>Осталось найти способ сложить строки в таблицу, о чем я с самого начала и говорил.


Евгений, здесь все ходы записаны, так что не не сложно тыкнуть вас фейсом в ваше же говно:

В сам язык имело смысл изначально завезти кодирование строковых литералов в виде "длина+текст", наравне со стандартным нулем в конце, что в итоге сделали в C++11 для string.


Никакого кодирования "длина+текст" в C++11 не сделали. Ни для строк, ни для чего-либо еще.

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

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

Остается только лишний раз показывать где вы снова жидко обделались.
Re[12]: Об эффективности виртуальных функций
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 06.08.24 08:31
Оценка:
Здравствуйте, karbofos42, Вы писали:

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


С чего б им жужжать, коли они на этих языках попросту не решают задач, для которых принято привлекать C/C++? Я сам езжу на машине с клиренсом в 16 см по асфальту, и тоже не жужжу.

K>Кому нужно что-то супер-мега оптимизированное и без лишнего — всегда можно взять или сделать стороннюю библиотеку и не прикручивать виртуализацию.


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

K>Вариант коллекций из C#/Java мне видится более удобный и безопасный в повседневном использовании, где никто байты не считает и миллионами записей не орудует.


Так те, кому не надо считать/орудовать, и пишут на C#/Java.

K>Против STL ничего не имею


А я имею. Но, что выросло — то выросло.

K>Вроде язык с контролем типов и максимально проверки вынесены в compile-time, а вроде в коллекцию bool легко int запишет с неявным преобразованием


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

K>и лови баг сиди.


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

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


Вы так и не поняли нюансов, которые Вам упорно пытаются объяснить.
Re[12]: Об эффективности виртуальных функций
От: пффф  
Дата: 06.08.24 09:37
Оценка:
Здравствуйте, karbofos42, Вы писали:

П>>А сейчас что мешает написать общий код?


K>Что это нужно делать задом-наперёд,


Что значит: "задом наперёд"?

K>многословно


Да не особенно


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


Как не надо — не занимается, когда надо — занимается. Есть конечно, некоторое количество сишечников, которые пишут на на C на С++. Есть некоторое количество неосиливших. Люди разные.


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


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


Определять, что у объекта тип не поменялся — он умеет, он не умеет заглядывать в объектный код, в котором лежит реализация виртуального метода, и определять, что size не поменялся.


П>>Нормально выглядит. Я не понимаю, что ты докопался до плюсов? Иди в шарповый форум, раз на шарпе пишешь, не надо предлагать переделать плюсики в шарп


K>Я не предлагаю ничего менять. Наглядно показываю как в плюсах ради экономии на тех же виртуальных вызовах пишут задом-наперёд и радуются.


Что значит: "задом наперёд"?

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


K>Опять же смотрим название темы.


И?
Re[10]: Об эффективности виртуальных функций
От: пффф  
Дата: 06.08.24 09:48
Оценка:
Здравствуйте, karbofos42, Вы писали:

П>>Мне коллекции C++ за счет одинаковых интерфейсов тоже видятся удобными.


K>Так у них нет одинаковых интерфейсов.


Есть конечно, просто это сделано не так, как ты привык, не через таблицу виртуальных методов


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


Всё тоже самое, что и у вас, только у нас в компайл тайме, а у вас в рантайме.


K>В своих классах тоже используете не наследование и виртуальные методы, а просто одинаково называете их и потом через шаблоны вызываете?


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


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



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


Это если интерфейсы контейнеров совпадают, и прокатывает утиная типизация


K>Ну, вот в жизни пишется как мне тут в теме несколько примеров с шаблонами привели?

K>Или всё же чаще хардкодится конкретный условный std::vector и методы все его принимают, т.к. нафиг надо шаблоны городить?

Когда как
Re[13]: Об эффективности виртуальных функций
От: karbofos42 Россия  
Дата: 06.08.24 09:50
Оценка:
Здравствуйте, пффф, Вы писали:

П>Что значит: "задом наперёд"?


Вместо того, чтобы просто написать: коллекция.добавить(10), нужно сначала подготовить вставлятор в эту коллекцию, потом сообщить ему, что нужно добавить 10, чтобы он уже добавил элемент в коллекцию.

П>Определять, что у объекта тип не поменялся — он умеет, он не умеет заглядывать в объектный код, в котором лежит реализация виртуального метода, и определять, что size не поменялся.


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

П>И?


"виртуальные функции сильно снижают быстродействие"
Re[11]: Об эффективности виртуальных функций
От: karbofos42 Россия  
Дата: 06.08.24 09:59
Оценка:
Здравствуйте, пффф, Вы писали:

П>Всё тоже самое, что и у вас, только у нас в компайл тайме, а у вас в рантайме.


Тут в соседней ветке ваш компайл тайм уже выстрелил тем, что молча int сложил в коллекции float и bool.
В C# я на этапе компиляции узнаю, что нужен ICollection<int>, а не ICollection<bool>

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


Да как-то я в компайл тайме большинство проблем узнаю

П>Это если интерфейсы контейнеров совпадают, и прокатывает утиная типизация


Так это в C++, а в C# все коллекции реализуют ICollection<T> или хотя бы IEnumerable<T> и типы контролируются штатно на этапе компиляции, не нужно ничего на шаблонах городить.
Re[12]: Об эффективности виртуальных функций
От: so5team https://stiffstream.com
Дата: 06.08.24 10:29
Оценка:
Здравствуйте, karbofos42, Вы писали:

K>Тут в соседней ветке ваш компайл тайм уже выстрелил тем, что молча int сложил в коллекции float и bool.


Все в рамках правил языка. Что просили у компилятора, то он вам и сделал.

K>В C# я на этапе компиляции узнаю, что нужен ICollection<int>, а не ICollection<bool>


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

Да и вообще предмет сопоставления Java/C# с C++ непонятен. Ниши этих языков разошлись давным-давно. Если у вас нет необходимости использовать C++ и делать все на C#, то какая разница как сделано в C++. Если же нужно все-таки пользоваться C++, то без разницы как сделано в C#.

Здесь свой монастырь, свой устав. Поменять вы его все равно не сможете.

Так в чем смысл?
Отредактировано 06.08.2024 11:13 so5team . Предыдущая версия .
Re[15]: Об эффективности виртуальных функций
От: пффф  
Дата: 06.08.24 10:36
Оценка:
Здравствуйте, Евгений Музыченко, Вы писали:

П>>те, кто под них пишет — конченные люди, их уже только могила исправит. И пишут они лютое говно.


ЕМ>Вот прям все, без исключения? А почему, собственно? Что, по-Вашему, делает их такими?


Отсутствие опыта решения сложных задач делает их такими


П>>Я знавал одного сишника/асмщика с PIC — на его код без слез смотреть было нельзя. Под MSC-51 сам писал. И много читал сишного кода. Тоже тоже очень хотелось плакать. Всё это было написано людьми, явно далекими от программирования, и ни о какой эффективности там говорить не приходилось.


ЕМ>А я видел немало кода, написанного вроде бы профессиональными программистами, но тоже хотелось плакать. Какой вывод-то?


Вывод такой, что ваше утверждение про сильных сишников, выходцев из среды разработки под уродцев, высосано из пальца


П>>Ни о каком промышленном серьёзном применении этого говна речи идти не может.


ЕМ>"Промышленное серьезное применение" — это не только сложные станки, выпускаемые сотнями-тысячами штук. Это любая индустрия с достаточно большими капиталовложениями и объемами производства.


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


ЕМ>Именно из-за устройства МК? Какие параметры МК обрекают любой код для него на говнистость?


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


П>>Это нельзя называть серьёзным промышленным применением, ничего сложного там и не делается.


ЕМ>А если этого выпускается тонны, и продается на миллиарды?


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


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


ЕМ>Да, и в каждые настольные часы вкорячить линукс. А кто за все это заплатит? STM-ки вроде как не бесплатные.


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


П>>Другое применение этих уродцев — это контроллеры стиральных машин


ЕМ>Которые выпускаются штучно, отчего встречаются очень редко.


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


П>>где оно решает мега сложные задачи по измерению температуры воды и её нагреву (там аж ПИД-регулятор надо делать, это да), да по смене режимов работы, включения мотора барабана и насосов на двухчасовом цикле стирки. Да, тут 5 Мгц частоты точно мало, тут 160 надо.


ЕМ>Про оценку распределения масс в барабане по соотношению токов в обмотках двигателя Вы явно не в курсе.


Покажите мне прошивку стиральной машины, где этим заморочились


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


ЕМ>Вот прям иногда? Если каждые часы, термометр, датчик дыма и прочая мелочь вокруг Вас станет разряжать свой источник не за год-два, а за две недели, Вы ничуть не расстроитесь?


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


П>>но квалификации тут не нужно никакой от слова вообще.


ЕМ>Изначально речь шла не о квалификации, а о возможности применения для всего этого более удобного и надежного языка, нежели ассемблер или C. Глядишь, и говнокода стало бы поменьше.


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


П>>прошивки к этим устройствам пишут не какие-то супер-эффективные сишники-программисты, прошивки к ним пишут инженеры-электронщики


ЕМ>Возможно, Вы не в курсе, но многие сильные программисты вышли из технарей, изучая программирование самостоятельно. А вот изначально подготовленные на профильных факультетах далеко не всегда демонстрируют хороший уровень.


Ещё больше вышло из получивших профильное образование


П>>Петров, у вас же в институте язык C давали? — Давали, один семестр. — Отлично, Петров, вот ты прошивку и напишешь".


ЕМ>И что, если бы Петрову давали не C, а C++ или Pascal, он написал бы хуже?


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


П>>А вы много вообще сишников знаете, и ещё и пишущих под контроллеры? Нету таких сишников, как класса.


ЕМ>Когда мне попадаются исходники прошивок для устройств, которые я использую, многие производят неплохое впечатление.


Исходники в студию.


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


ЕМ>Каким образом все эти качества могут концентрироваться в плюсовом компиляторе, но избегать попадания в сишный? Если в компиляторе есть соответствующая логика — он будет оптимизировать до упора, если ее нет — будет делать код, как придется. Стандарты C++ не устанавливают конкретных требований к оптимизации, за исключением некоторых явно оговоренных. А многие компиляторы изначально умеют и C, и C++. Функционально эквивалентные исходники они чаще всего компилируют в один и тот же код.


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


ЕМ>>>Просто писать будет удобнее, код будет более читаемым, ошибки делать сложнее, а вылавливать — легче.


П>>Это вы про сишечку?


ЕМ>Это я про плюсики по сравнению с сишечкой.


Что-то я тут уже нить потерял. Вы о чем?


П>>Я, как минимум, написал один HTTP-сервер на сишечке


ЕМ>Это считается сложным проектом для C? Не знал, честно. Вот, например, Simple HTTP Server — цельных 25 килобайт исходник. Или Ваш был сильно круче?


Да, мой был сильно круче, потому что не просто раздавал файлы с диска, а был приложением по настройке девайса, и генерил контент и обрабатывал пользовательский ввод, там было что-то недо-CMS



П>>что написали на сишечке вы?


ЕМ>Успел написать пару драйверов средней сложности, несколько приложений для работы со звуком, кучку разных мелких утилит. Делал оконную подсистему и музыкальный секвенсор, но бросил.


Бросили, на сишечке тяжело тащить стало?


ЕМ>Можем помериться приборами по ассемблерам. Я на одном ассемблере когда-то написал многопользовательскую интерактивную систему составления программ для графопостроителя и управления заданиями для него (это когда в школе учился), а на другом — программу составления и печати спецификаций оборудования для газодобывающей промышленности, по набору заданных шаблонов (эту спихнул в качестве дипломной работы в институте, чтоб отдельной темы не брать). А в машинных кодах (ибо на той машине ассемблера не было) я написал дизассемблер (чтоб удобнее было возиться с кодами) и визуальный текстовый редактор с форматированием и печатью в несколько столбцов. И не скажу, что это были сложные задачи — вполне себе ординарные.


Они сложные только для пишущего на асме или на сишечке — объем работы достаточно велик.

П>>Я могу примерно прикинуть мою производительность на масме, и на плюсиках. Субъективно разница где-то от 1000 до 10000 раз


ЕМ>Как-то слишком разительно.


С чего бы? Я на плюсах напишу один раз обобщенный код, а на асме буду писать макросы, а потом всё это каждый раз отлаживать


ЕМ>Ну, или для Вас ассемблеры просто сильно непривычны.


Да, x86 я на масме немного трогал, но быстро соскочил на сишечку, а потом на плюсики, в основном опыт был на Z80.


П>>Код среднего плюсовика всегда выиграет у кода среднего сишечника по скорости.


ЕМ>Да не выиграет он всегда. Если и тот, и другой делают код согласно устоявшимся правилам и рекомендациям, то где-то будет быстрее на C за счет простоты, где-то — на плюсах за счет выразительности. А если как попало, то и там, и там будет медленно.


Не очень понятно, почему на сишечке будет быстрее за счёт простоты? На плюсах обязательно писать сложно, если напишешь просто, коллеги засмеют, так что ли?
Плюсовый код будет быстрее за счёт возможностей компилятора по оптимизации.
Re[14]: Об эффективности виртуальных функций
От: пффф  
Дата: 06.08.24 10:40
Оценка:
Здравствуйте, karbofos42, Вы писали:

П>>Что значит: "задом наперёд"?


K>Вместо того, чтобы просто написать: коллекция.добавить(10), нужно сначала подготовить вставлятор в эту коллекцию, потом сообщить ему, что нужно добавить 10, чтобы он уже добавил элемент в коллекцию.


можно просто написать: коллекция.push_back(10)


П>>Определять, что у объекта тип не поменялся — он умеет, он не умеет заглядывать в объектный код, в котором лежит реализация виртуального метода, и определять, что size не поменялся.


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


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


П>>И?


K>"виртуальные функции сильно снижают быстродействие"


Снижают
Re[12]: Об эффективности виртуальных функций
От: пффф  
Дата: 06.08.24 10:47
Оценка: :)
Здравствуйте, karbofos42, Вы писали:

П>>Всё тоже самое, что и у вас, только у нас в компайл тайме, а у вас в рантайме.


K>Тут в соседней ветке ваш компайл тайм уже выстрелил тем, что молча int сложил в коллекции float и bool.


Ну если ты все варниги отключил, то ты сам себе буратино


K>В C# я на этапе компиляции узнаю, что нужен ICollection<int>, а не ICollection<bool>


В плюсах я тоже узнаю, если не буду игнорировать предупреждения


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


K>Да как-то я в компайл тайме большинство проблем узнаю


Ну, я рад за тебя


П>>Это если интерфейсы контейнеров совпадают, и прокатывает утиная типизация


K>Так это в C++, а в C# все коллекции реализуют ICollection<T> или хотя бы IEnumerable<T> и типы контролируются штатно на этапе компиляции, не нужно ничего на шаблонах городить.


Рад за тебя
Re[15]: Об эффективности виртуальных функций
От: so5team https://stiffstream.com
Дата: 06.08.24 11:02
Оценка: +1
Здравствуйте, Евгений Музыченко, Вы писали:

ЕМ>Это считается сложным проектом для C? Не знал, честно. Вот, например, Simple HTTP Server — цельных 25 килобайт исходник.


А вы в код заглядывали? Что там комментарии типа "IMPLEMENT ME" делают?
Re[5]: Об эффективности виртуальных функций
От: Nuzhny Россия https://github.com/Nuzhny007
Дата: 06.08.24 11:05
Оценка:
Здравствуйте, Евгений Музыченко, Вы писали:

ЕМ>Если объектов единицы-десятки миллионов, и в каждом до десятков байт, то можно обойтись и 32-разрядными адресами, это будет по четыре байта. Если в объекте сорок байт, то четыре байта — 10%. Это считается много?


Не очень понял, откуда вдруг 4 байта возникли, если их 8. Делать 32-х разрядные приложения?
Re[5]: Об эффективности виртуальных функций
От: пффф  
Дата: 06.08.24 11:10
Оценка:
Здравствуйте, Евгений Музыченко, Вы писали:


N>>Восемь лишних байт на класс в каждом экземпляре.


ЕМ>Если объектов единицы-десятки миллионов, и в каждом до десятков байт, то можно обойтись и 32-разрядными адресами, это будет по четыре байта. Если в объекте сорок байт, то четыре байта — 10%. Это считается много?


Вроде, у создателей Excel была проблема, когда каждая ячейка была ком объектом, памяти жрало как не в себя. Сейчас конечно память не ресурс, жри не хочу
Re[11]: Об эффективности виртуальных функций
От: пффф  
Дата: 06.08.24 11:15
Оценка: :)
Здравствуйте, T4r4sB, Вы писали:

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


TB>Жесть


Человек пишет на шарпе, чего с него взять. Чего он на этот форум вообще забрел
Re[10]: Об эффективности виртуальных функций
От: пффф  
Дата: 06.08.24 11:19
Оценка:
Здравствуйте, karbofos42, Вы писали:

BFE>>Ну так возьмите vector и пользуйте.


K>Потом все вызовы придётся переписывать, если захочется поменять вектор на множество или какой другой контейнер.


Вектор и множество — принципиально разные типы контейнеров. Если вам захотелось поменять один на другой, это повод хорошенько задуматься
Re[16]: Об эффективности виртуальных функций
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 06.08.24 11:27
Оценка:
Здравствуйте, so5team, Вы писали:

S>А вы в код заглядывали?


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

S>Что там комментарии типа "IMPLEMENT ME" делают?


Да, не заметил, что это заготовка.

Вот рабочий сервер в 200 строк на C.

Вот однопоточный и многопоточный серверы, где-то на 100 кб исходников.
Re[17]: Об эффективности виртуальных функций
От: so5team https://stiffstream.com
Дата: 06.08.24 11:39
Оценка: 1 (1)
Здравствуйте, Евгений Музыченко, Вы писали:

ЕМ>Вот рабочий сервер в 200 строк на C.


ЕМ>Вот однопоточный и многопоточный серверы, где-то на 100 кб исходников.


Евгений, вам на подумать: один из самых активно используемых и проверенных в продакшене парсеров HTTP протокола, llhttp, имеет реализацию ~300Kb. Причем, как я понял, авторы сделали это посредством генерации кода из TypeScript-а, т.к. писать надежно на чистом Си -- это убиться можно.

И если вы находите какое-то говно в 200 строк, то это всего лишь означает до нормальной поддержки HTTP там как до Луны.
Re[13]: Об эффективности виртуальных функций
От: karbofos42 Россия  
Дата: 06.08.24 11:43
Оценка:
Здравствуйте, so5team, Вы писали:

S>Все в рамках правил языка. Что просили у компилятора, то он вам и сделал.


Так себе компайл тайм, который якобы все ошибки показывает.
В С++ вроде и по максимуму на этапе компиляции всё высчитывается и контролируется, но зато язык столько всего позволяет, что потенциально пропускается куча глупых "опечаток".

S>Зато у вас негров линчуют вы не сможете своей process, которая оперирует только ICollection, дать указание выводить значения на консоль, вместо сохранения в контейнер. Ну или же вам придется делать реализацию ICollection для этих целей.


Ни разу как-то в жизни не сталкивался с необходимостью работать с консолью как с контейнером.
Если нужен универсальный метод, который сможет и в консоль писать, то можно написать что-то типа:
public void Process(IEnumerable<int> items, Action<int> target1, Action<int> target2)
{
  foreach (var value in items)
  {
    if (value % 2 == 0) { target1(value); }
    else { target2(value); }
  }
}
...
ICollection<int> list = new List<int>();
ICollection<int> set = new HashSet<int>();
Process(new int[] {1, 2, 3, 4, 5}, list.Add, set.Add);
Process(new int[] {1, 2, 3, 4, 5}, Console.WriteLine, (v) => Console.WriteLine($"_{v}"));

уже ближе к C++ по упоротости получается )

S>Да и вообще предмет сопоставления Java/C# с C++ непонятен. Ниши этих языков разошлись давным-давно. Если у вас нет необходимости использовать C++ и делать все на C#, то какая разница как сделано в C++. Если же нужно все-таки пользоваться C++, то без разницы как сделано в C#.


Java и C# тут сугубо как пример как можно было сделать контейнеры с виртуальными методами, а не сопоставление что лучше или хуже.
Есть STL, которую вероятно писали не дураки и по какой-то причине от виртуализации там по-моему совсем отказались.
На мой взгляд коллекции и их интерфейсы в C#/Java удобнее в 99% случаев, т.к. в большинстве своём выполняются типовые операции перебора, добавления, поиска.
В STL это типовое всё либо прибивается к конкретному типу коллекции и дальше её сложнее поменять, если понадобится.
Либо там придётся больше писать и до кучи получишь меньше контроля за типами объектов.
Пример этот не взлетел, т.к. пошли разговоры о том, что это в Java/C# неудобные и неправильные коллекции, унифицированный Add не нужон и не понятен, а в STL всё сделано лучше.
Если бы взлетел, можно было достаточно простой бенчмарк изобразить со сравнением STL контейнеров и аналогов с реализацией общих интерфейсов Iterable и Collection как в Java, например.

S>Так в чем смысл?


Любой в этой теме может привести свой пример, на котором наглядно можно продемонстрировать насколько виртуальные методы в реальности дёшевы в использовании или же наоборот это дорогостоящая вещь, которую имеет смысл обходить стороной как это сделали в STL. У меня очевидно не получилось с примером
Re[15]: Об эффективности виртуальных функций
От: karbofos42 Россия  
Дата: 06.08.24 11:46
Оценка:
Здравствуйте, пффф, Вы писали:

П>можно просто написать: коллекция.push_back(10)


std::set это не одобрит

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


Я хохотался с простого и элегантного плюсового кода
Re[11]: Об эффективности виртуальных функций
От: karbofos42 Россия  
Дата: 06.08.24 12:01
Оценка: :)
Здравствуйте, пффф, Вы писали:

П>Вектор и множество — принципиально разные типы контейнеров. Если вам захотелось поменять один на другой, это повод хорошенько задуматься


Так я задумался и увидел, что в нужной функции просадку даёт поиск элементов в векторе, т.к. идёт перебором.
Хотелось бы как-то легко и просто оценить поведение на этих данных множеств. Может они памяти слишком много выжрут и не подойдут или просядут в других функциях.
А то будешь сидеть пол дня менять вектор на множество, результат не понравится и в итоге оставишь вектор, просто элементы отсортируешь и перебор на бинарный поиск заменишь, чтобы хоть немного быстрее работало.
Но конечно плюсовики все сразу при чтении задачи знают с уверенностью в 100% какой контейнер использовать, суровые реалии не меняются и таких задач не встаёт.
А если и встают, то все точно знают сколько выигрыша даст другой контейнер, а где сколько проиграет текущему.
Re[14]: Об эффективности виртуальных функций
От: so5team https://stiffstream.com
Дата: 06.08.24 12:03
Оценка:
Здравствуйте, karbofos42, Вы писали:

S>>Все в рамках правил языка. Что просили у компилятора, то он вам и сделал.


K>Так себе компайл тайм, который якобы все ошибки показывает.


Вынужден повторить: неявное приведение от int к bool или к float -- это не ошибка с точки зрения языка. Это легальная операция.

K>В С++ вроде и по максимуму на этапе компиляции всё высчитывается и контролируется, но зато язык столько всего позволяет, что потенциально пропускается куча глупых "опечаток".


Да, C++ печально известен этим качеством.

Благо, сейчас не желающие иметь дело с C++ имеют просто шикарный выбор альтернатив: Java/Scala/Kotlin, C#/F#, Go, Rust.

Тем же, кто по каким-то причинам остаются в C++, живут в соответствии с правилами C++.

K>Ни разу как-то в жизни не сталкивался с необходимостью работать с консолью как с контейнером.


Мне, например, сложно вспомнить когда в последний раз приходилось менять vector на set. Тем не менее, этот момент мы обсуждаем.

K>Если нужен универсальный метод, который сможет и в консоль писать, то можно написать что-то типа:

K>
K>public void Process(IEnumerable<int> items, Action<int> target1, Action<int> target2)
K>


И получилось, что ICollection пошли лесом.

S>>Да и вообще предмет сопоставления Java/C# с C++ непонятен. Ниши этих языков разошлись давным-давно. Если у вас нет необходимости использовать C++ и делать все на C#, то какая разница как сделано в C++. Если же нужно все-таки пользоваться C++, то без разницы как сделано в C#.


K>Java и C# тут сугубо как пример как можно было сделать контейнеры с виртуальными методами, а не сопоставление что лучше или хуже.


Ну OK. Все равно не понятен выхлоп от такого сравнения.

K>Есть STL, которую вероятно писали не дураки и по какой-то причине от виртуализации там по-моему совсем отказались.


Потому что виртуальные вызовы не бесплатны. Даже если они добавляют 1.5% просадки производительности, то для мира C++ это все равно может оказаться непозволительно дорого.

K>На мой взгляд коллекции и их интерфейсы в C#/Java удобнее в 99% случаев, т.к. в большинстве своём выполняются типовые операции перебора, добавления, поиска.


И это замечательно.
Даже в С++ в итоге добавили ranges, т.к. пара [begin, end) местами, неудобна для использования. Так что гибкость итераторов имеет свою цену.

K>В STL это типовое всё либо прибивается к конкретному типу коллекции и дальше её сложнее поменять, если понадобится.


Зато получаем максимальную эффективность. Таков путь (c)

K>Либо там придётся больше писать и до кучи получишь меньше контроля за типами объектов.


Зависит от того, как писать.

S>>Так в чем смысл?


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


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

Вряд ли кто-то такое может опубликовать из своей профессиональной деятельности.
А готовить голый пример (вот то же перемножение матриц, которое как раз должно дать миллионы (если не миллиарды) вызовов в секунду) -- это же не менее часа работы на пару реализаций, их тестирование, бенчмаркинг, оформление результатов сюда в форум... Уж лучше я потрачу этот час на то, что мне реальные деньги принесет.
Re[11]: Об эффективности виртуальных функций
От: B0FEE664  
Дата: 06.08.24 12:29
Оценка:
Здравствуйте, Евгений Музыченко, Вы писали:

ЕМ>>>задачу создания таблиц строк вида "длина+текст" это все равно не решает, приходится извращаться, как и раньше.

BFE>>А string_view на что?
ЕМ>Так все равно ж исходные литералы лежат отдельно, с нулями в конце, а рядом лежат ссылки на них в объектах string_view.

В рамках языка C++ нет смысла делать что-то большее.
И каждый день — без права на ошибку...
Re[8]: Об эффективности виртуальных функций
От: B0FEE664  
Дата: 06.08.24 12:45
Оценка:
Здравствуйте, Евгений Музыченко, Вы писали:

BFE>>Никто не использует настоящий С++ просто потому, что его никто не знает.

ЕМ>И его не существует?
Существует.
Просто каждый отдельный знает и использует только часть возможностей C++

ЕМ> Сколько боролись с самомодификацией кода, чтоб снова к ней вернуться.

Кто боролся и кто вернулся?
И каждый день — без права на ошибку...
Re[12]: Об эффективности виртуальных функций
От: пффф  
Дата: 06.08.24 12:50
Оценка: +1 :))
Здравствуйте, karbofos42, Вы писали:

П>>Вектор и множество — принципиально разные типы контейнеров. Если вам захотелось поменять один на другой, это повод хорошенько задуматься


K>Так я задумался и увидел, что в нужной функции просадку даёт поиск элементов в векторе, т.к. идёт перебором.


А задуматься надо было тогда, когда ты выбирал контейнер. Элементы уникальные? Тогда set. Не уникальные? Тогда set нельзя. Порядок важен? Вектор или очередь. Нужен поиск? Тогда сортированный вектор и вставка в нужную позицию.
В общем, тебя надо было гнать сразу, когда ты не тот контейнер выбрал


K>Хотелось бы как-то легко и просто оценить поведение на этих данных множеств. Может они памяти слишком много выжрут и не подойдут или просядут в других функциях.

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

Менять придётся в паре мест, не больше, если всё правильно сделано


K>Но конечно плюсовики все сразу при чтении задачи знают с уверенностью в 100% какой контейнер использовать, суровые реалии не меняются и таких задач не встаёт.


Не только плюсовики, а любой нормальный программист


K>А если и встают, то все точно знают сколько выигрыша даст другой контейнер, а где сколько проиграет текущему.


Ну, вообще-то надо знать контейнеры, которыми пользуешься, сложность различных операций с ними, как хранят данные, и тп. Ты показал уровень студента, пишущего лабу
Re[10]: Об эффективности виртуальных функций
От: B0FEE664  
Дата: 06.08.24 13:00
Оценка:
Здравствуйте, so5team, Вы писали:

ЕМ>>>>Но удобство C++ как раз в том, что на нем можно писать всё.

S>>>Евгений, блин, уже лет 20 как пора забыть про эту чушь.
BFE>>Почему?
S>Экономическая целесообразность.
Почему именно экономическая, а не экологическая?

BFE>>Разве есть что-то, что невозможно написать на C++?

S>Я бы хотел посмотреть на C++ный вариант, скажем, ActiveRecord из Ruby-On-Rails.
смотрите
И каждый день — без права на ошибку...
Re[11]: Об эффективности виртуальных функций
От: so5team https://stiffstream.com
Дата: 06.08.24 13:08
Оценка:
Здравствуйте, B0FEE664, Вы писали:

ЕМ>>>>>Но удобство C++ как раз в том, что на нем можно писать всё.

S>>>>Евгений, блин, уже лет 20 как пора забыть про эту чушь.
BFE>>>Почему?
S>>Экономическая целесообразность.
BFE>Почему именно экономическая, а не экологическая?

Потому что там, где сижу я, программы пишут не из любви к искусству, а для получения прибыли. И если конкретная технология (тот же C++) снижает эту самую прибыль и увеличивает риски, то эта технология заменяется на что-то более полезное. Т.е. тупо денежные затраты решают.

BFE>>>Разве есть что-то, что невозможно написать на C++?

S>>Я бы хотел посмотреть на C++ный вариант, скажем, ActiveRecord из Ruby-On-Rails.
BFE>смотрите

Это даже не жалкое подобие судя по тому, что показано в README, да еще и вряд ли нужное даже его автору. ЧТД.
Re[16]: Об эффективности виртуальных функций
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 06.08.24 13:14
Оценка: :)
Здравствуйте, пффф, Вы писали:

П>Отсутствие опыта решения сложных задач делает их такими


Какие задачи (на уровне МК или обычного компьютера) Вы согласны считать "достаточно сложными" для получения адекватного опыта в программировании? Какие факторы превращают "несложную" задачу в "сложную"? А на ваших STMках какие задачи решаются?

П>ваше утверждение про сильных сишников, выходцев из среды разработки под уродцев, высосано из пальца


Я не делал такого утверждения. Вы слишком произвольно интерпретируете мои слова.

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


Я утверждал, что и на 8-разрядных МК бывают достаточно сложные (для их уровня) задачи, а про закалку я вообще ничего не говорил.

П>Убогость и огранниченность возможностей -> невозможность решать сложные задачи


То есть, на ранних компьютерах, возможности которых были сравнимы со многими простыми МК, сложных задач не решалось?

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

П>никто не будет для дверного звонка нанимать дорогих профессиональных программистов


Хороший программист (да и вообще любой профессионал) не обязательно дорогой. Многим просто нравится их работа, и они не ищут заработка сверх того, что достаточно для покрытия их потребностей.

Кстати, Вы забываете, что немало разработчиков железа на МК пишут не только прошивки, но и "сопутствующий" софт для "взрослых" компьютеров.

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


Ваш "средний плюсовик" эти полдня будет писать с исключениями, std::chrono, std::thread, std::async и подобным, затем попытается скомпилировать, внезапно обнаружит, что втуда этого не завезли, оставшиеся полдня потратит на гугление по запросам "std для 8-разрядного контроллера скачать бесплатно и без SMS". На следующий день потребует дать ему "нормальный процессор вместо этого говна", будет послан, и дальше месяц будет писать так же, как и сишник.

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

ЕМ>>Про оценку распределения масс в барабане по соотношению токов в обмотках двигателя Вы явно не в курсе.


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


Двоичный дамп устроит? Если да, то могу поискать. Исходников в свободном доступе не видел. А то, что в стиральных машинах (по крайней мере, в подавляющем большинстве) датчиков вибрации нет, но дисбаланс они чуют и пытаются исправлять — факт. В технической документации кое-где пишут, каким образом.

П>и да, прошивку для таких устройств пишет любой инженер за месяц, а средний плюсовик — за полдня.


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

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


Где шла? Я такого не говорил. Вы, судя по тому, что возражаете — вроде бы тоже.

ЕМ>>многие сильные программисты вышли из технарей, изучая программирование самостоятельно


П>Ещё больше вышло из получивших профильное образование


Очень сильно зависит от места получения образования. В РФ всего несколько мест систематически и предсказуемо выпускают сильных программистов. Остальные выпускают ширпотреб, который пристраивается в основном на 1С, веб, кодит типовые задачи по четкому ТЗ, и так далее.

П>В плюсах библиотеки в основном хидер-онли, и вот практически буквально всё доступно компилятору для анализа.


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

ЕМ>>Это я про плюсики по сравнению с сишечкой.


П>Что-то я тут уже нить потерял. Вы о чем?


О том, что писать на плюсиках, даже "в стиле C", все равно удобнее и надежнее, чем на чистом C. Не обязательно использовать std и лямбды, чтобы она стала "программой на плюсах".

П>Да, мой был сильно круче, потому что не просто раздавал файлы с диска, а был приложением по настройке девайса, и генерил контент и обрабатывал пользовательский ввод, там было что-то недо-CMS


На мой взгляд, это все достаточно ординарные задачи средней сложности, я не стал бы иллюстрировать ими свое умение программировать. Чтобы решить такую задачу, достаточно прочитать спецификацию протокола, описание API сетевых сервисов, формат HTML, накидать ТЗ для недо-CMS, а дальше просто это программировать, шаг за шагом. Здесь нигде не возникает вопросов "блин, а как же это сделать-то?" — все уже давно обкатано, готовых решений полно, при желании можно почти все сделать на копипасте.

А вот когда линейка реально массовых (десятки-сотни миллионов в год) изделий, основанная на МК ограниченной мощности, упирается в его пределы, нередко выгоднее нанять крутого дорогого спеца, который изыщет резервы, чем переделывать всю линейку на более мощный, чтоб под него могли писать "средние плюсовики", и чтоб покупатели бухтели, что заряда стало хватать не на неделю, а на сутки.

П>Бросили, на сишечке тяжело тащить стало?


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

П>Они сложные только для пишущего на асме или на сишечке — объем работы достаточно велик.


Я как раз не считал их сложными, ибо большое количество кода само по себе не означает сложности. Сложность — это то, для чего нет готовых путей решения, которые достаточно "просто применить". Задачу Дейкстры про вагоны и туалеты знаете?

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


То есть, на плюсах Вы систематически решаете однотипные задачи?

П>почему на сишечке будет быстрее за счёт простоты?


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

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

П>Плюсовый код будет быстрее за счёт возможностей компилятора по оптимизации.


Вы не замечаете, что это уже выглядит, как мантра?
Re[6]: Об эффективности виртуальных функций
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 06.08.24 13:15
Оценка:
Здравствуйте, Nuzhny, Вы писали:

N>Делать 32-х разрядные приложения?


Если задача позволяет — делать. В этом нет ничего стыдного.
Re[13]: Об эффективности виртуальных функций
От: karbofos42 Россия  
Дата: 06.08.24 13:17
Оценка: :))
Здравствуйте, пффф, Вы писали:

П>А задуматься надо было тогда, когда ты выбирал контейнер. Элементы уникальные? Тогда set. Не уникальные? Тогда set нельзя. Порядок важен? Вектор или очередь. Нужен поиск? Тогда сортированный вектор и вставка в нужную позицию.


Гениально. Сразу видно эксперта

П>В общем, тебя надо было гнать сразу, когда ты не тот контейнер выбрал


Тайну открою: программистам периодически приходится лезть в чужой код.
А ещё иногда может измениться суровая реальность и предыдущие правильные решения перестают устраивать.

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


Ну, куда мне до тебя, у которого set от vector'а отличается уникальностью элементов
Re[12]: Об эффективности виртуальных функций
От: B0FEE664  
Дата: 06.08.24 14:12
Оценка: :)
Здравствуйте, so5team, Вы писали:

BFE>>Почему именно экономическая, а не экологическая?

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

S>И если конкретная технология (тот же C++) снижает эту самую прибыль и увеличивает риски, то эта технология заменяется на что-то более полезное.

А если увеличивает и прибыль и риски, то тогда как?

S>Т.е. тупо денежные затраты решают.

Значит победит C.

BFE>>>>Разве есть что-то, что невозможно написать на C++?

S>>>Я бы хотел посмотреть на C++ный вариант, скажем, ActiveRecord из Ruby-On-Rails.
BFE>>смотрите
S>Это даже не жалкое подобие судя по тому, что показано в README, да еще и вряд ли нужное даже его автору. ЧТД.
Ну вот, значит первая же ссылка в поиске выдаёт уже что-то.
Значит написать можно.
ЧТД
И каждый день — без права на ошибку...
Re[12]: Об эффективности виртуальных функций
От: T4r4sB Россия  
Дата: 06.08.24 14:53
Оценка: :)
Здравствуйте, karbofos42, Вы писали:

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


TB>>Во-первых, мегауниверсальный метод нужен редко, и тогда принимают пару итераторов.


K>Никогда не бывает такого, что ошиблись с выбором контейнера или объём/характер данных несколько изменился, что требуется вектор заменить на хэш-таблицу с быстрым поиском?


Бывает.
Берешь и меняешь. А причем тут виртуальные функции и универсальность?
Нет такой подлости и мерзости, на которую бы не пошёл gcc ради бессмысленных 5% скорости в никому не нужном синтетическом тесте
Re[13]: Об эффективности виртуальных функций
От: so5team https://stiffstream.com
Дата: 06.08.24 15:34
Оценка:
Здравствуйте, B0FEE664, Вы писали:

BFE>>>Почему именно экономическая, а не экологическая?

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

И в каком направлении? На ум приходит разве что наука или сопровождение легаси в условном Яндексе.

S>>И если конкретная технология (тот же C++) снижает эту самую прибыль и увеличивает риски, то эта технология заменяется на что-то более полезное.

BFE>А если увеличивает и прибыль и риски, то тогда как?

А это где в софтостроении такой подход к рискам?

S>>Т.е. тупо денежные затраты решают.

BFE>Значит победит C.

Скорее Go, Java и C#, возможно где-то и Rust.

BFE>>>>>Разве есть что-то, что невозможно написать на C++?

S>>>>Я бы хотел посмотреть на C++ный вариант, скажем, ActiveRecord из Ruby-On-Rails.
BFE>>>смотрите
S>>Это даже не жалкое подобие судя по тому, что показано в README, да еще и вряд ли нужное даже его автору. ЧТД.
BFE>Ну вот, значит первая же ссылка в поиске выдаёт уже что-то.

Тут уже Музыченко привел ссылку на заброшенный много лет назад HTTP-сервер на Си. Как оказалось даже не рабочий. Вы пока движетесь по его стопам.

BFE>Значит написать можно.


Смешно.

BFE>ЧТД


А это уже не смешно.
Re[14]: Об эффективности виртуальных функций
От: B0FEE664  
Дата: 06.08.24 15:44
Оценка:
Здравствуйте, so5team, Вы писали:

BFE>>>>Почему именно экономическая, а не экологическая?

S>>>Потому что там, где сижу я, программы пишут не из любви к искусству, а для получения прибыли.
BFE>>Место работы можно и поменять.
S>И в каком направлении? На ум приходит разве что наука или сопровождение легаси в условном Яндексе.
В таком, где деньги не главное.

S>>>И если конкретная технология (тот же C++) снижает эту самую прибыль и увеличивает риски, то эта технология заменяется на что-то более полезное.

BFE>>А если увеличивает и прибыль и риски, то тогда как?
S>А это где в софтостроении такой подход к рискам?
Много где. Везде, где переходят с C# на C++.

S>>>Т.е. тупо денежные затраты решают.

BFE>>Значит победит C.
S>Скорее Go, Java и C#, возможно где-то и Rust.
Не-а. C. Большинство бесплатных проектов на C. Тот же Linux.

S>Тут уже Музыченко привел ссылку на заброшенный много лет назад HTTP-сервер на Си. Как оказалось даже не рабочий. Вы пока движетесь по его стопам.

Nginx написан на C и используется повсеместно.

BFE>>Значит написать можно.

S>Смешно.
Почему? Оно же бесплатное, а согласно вам: "тупо денежные затраты решают".
(Не, я ни в коем случае не рекомендую, я вообще это поделие первый раз в жизни вижу)

BFE>>ЧТД

S>А это уже не смешно.
Вы думаете это единственная вот такая библиотека написанная на C++ для работы с базами данных? Да их тысячи разной степени качества, скорости и удобства.
И каждый день — без права на ошибку...
Re[15]: Об эффективности виртуальных функций
От: so5team https://stiffstream.com
Дата: 06.08.24 15:58
Оценка:
Здравствуйте, B0FEE664, Вы писали:

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

BFE>>>Место работы можно и поменять.
S>>И в каком направлении? На ум приходит разве что наука или сопровождение легаси в условном Яндексе.
BFE>В таком, где деньги не главное.

Конкретнее, пожалуйста. Общих слов я и сам могу наговорить с три короба.

S>>>>И если конкретная технология (тот же C++) снижает эту самую прибыль и увеличивает риски, то эта технология заменяется на что-то более полезное.

BFE>>>А если увеличивает и прибыль и риски, то тогда как?
S>>А это где в софтостроении такой подход к рискам?
BFE>Много где.

Пару имен можно?

BFE>Везде, где переходят с C# на C++.


Где-то и с C++ на Rust переходят. Так что без конкретики не считается.

S>>>>Т.е. тупо денежные затраты решают.

BFE>>>Значит победит C.
S>>Скорее Go, Java и C#, возможно где-то и Rust.
BFE>Не-а. C. Большинство бесплатных проектов на C. Тот же Linux.

Работа над бесплатными проектами должна кем-то оплачиваться.

S>>Тут уже Музыченко привел ссылку на заброшенный много лет назад HTTP-сервер на Си. Как оказалось даже не рабочий. Вы пока движетесь по его стопам.

BFE>Nginx написан на C и используется повсеместно.

Вас понесло в какую-то другую сторону. Я намекнул на то, что аналог ActiveRecord на C++ не написать. Вы в качестве опровержения привели что-то, что даже отдаленно не напоминает ActiveRecord. Тем самым уподобились г-н Музыченко, который вывалил на собеседника первое попавшееся говно.

BFE>>>Значит написать можно.

S>>Смешно.
BFE>Почему?

Потому что оно, даже бесплатное, явно показывает, что написать ActiveRecord на C++ не удалось.

BFE>>>ЧТД

S>>А это уже не смешно.
BFE>Вы думаете это единственная вот такая библиотека написанная на C++ для работы с базами данных? Да их тысячи разной степени качества, скорости и удобства.

Из нормальных в свое время было найдено всего две -- soci и otl. Но это совсем другой уровень. Однако, чтобы это понять, вам нужно как-то познакомиться с Ruby и ActiveRecord.
Re[16]: Об эффективности виртуальных функций
От: B0FEE664  
Дата: 06.08.24 16:27
Оценка:
Здравствуйте, so5team, Вы писали:

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

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

S>>>>>И если конкретная технология (тот же C++) снижает эту самую прибыль и увеличивает риски, то эта технология заменяется на что-то более полезное.

BFE>>>>А если увеличивает и прибыль и риски, то тогда как?
S>>>А это где в софтостроении такой подход к рискам?
BFE>>Много где.
S>Пару имен можно?
Везде, где пишут на C++.

BFE>>Везде, где переходят с C# на C++.

S>Где-то и с C++ на Rust переходят. Так что без конкретики не считается.
NDA

BFE>>Не-а. C. Большинство бесплатных проектов на C. Тот же Linux.

S>Работа над бесплатными проектами должна кем-то оплачиваться.
Но при этом любое коммерческое предприятие их может использовать совершенно бесплатно.

S>Вас понесло в какую-то другую сторону. Я намекнул на то, что аналог ActiveRecord на C++ не написать. Вы в качестве опровержения привели что-то, что даже отдаленно не напоминает ActiveRecord. Тем самым уподобились г-н Музыченко, который вывалил на собеседника первое попавшееся говно.

Ваша оценка качества основана на чём?

BFE>>>>Значит написать можно.

S>>>Смешно.
BFE>>Почему?
S>Потому что оно, даже бесплатное, явно показывает, что написать ActiveRecord на C++ не удалось.
Разве? А по ссылке что?

S>Из нормальных в свое время было найдено всего две -- soci и otl. Но это совсем другой уровень. Однако, чтобы это понять, вам нужно как-то познакомиться с Ruby и ActiveRecord.

Я не вижу принципиальной разницы между ActiveRecord на Ruby и ActiveRecord придуманный в Microsoft в прошлом веке. Укажите на неё, если можете.
И каждый день — без права на ошибку...
Re[17]: Об эффективности виртуальных функций
От: so5team https://stiffstream.com
Дата: 06.08.24 17:37
Оценка: +1
Здравствуйте, B0FEE664, Вы писали:

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

S>>Вас понесло в какую-то другую сторону. Я намекнул на то, что аналог ActiveRecord на C++ не написать. Вы в качестве опровержения привели что-то, что даже отдаленно не напоминает ActiveRecord. Тем самым уподобились г-н Музыченко, который вывалил на собеседника первое попавшееся говно.

BFE>Ваша оценка качества основана на чём?

Если вы о ссылке, которую привел Музыченко, то на основании кода по этой ссылке.
Если вы о своей ссылке, то на том, что я помню из RoR-овского ActiveRecord.

S>>Потому что оно, даже бесплатное, явно показывает, что написать ActiveRecord на C++ не удалось.

BFE>Разве?

Да.

BFE>А по ссылке что?


Какое-то жалкое подобие. Даже не так: попытка сделать какое-то жалкое подобие.

S>>Из нормальных в свое время было найдено всего две -- soci и otl. Но это совсем другой уровень. Однако, чтобы это понять, вам нужно как-то познакомиться с Ruby и ActiveRecord.

BFE>Я не вижу принципиальной разницы между ActiveRecord на Ruby и ActiveRecord придуманный в Microsoft в прошлом веке. Укажите на неё, если можете.

Что такое ActiveRecord от Microsoft?
Re: Об эффективности виртуальных функций
От: T4r4sB Россия  
Дата: 06.08.24 19:50
Оценка: +1
Здравствуйте, Евгений Музыченко, Вы писали:

ЕМ>что многим программистам, в том числе системным, "было трудно поверить в то, что виртуальные функции могут быть достаточно быстрыми".


А теперь серьёзно.
Универсальный виртуальный интерфейс контейнеров это хрень полная, понятно, проблема С++ного подхода вообще не здесь

На деле выбирать приходится между скоростью исполнения и скоростью разработки.
Виртуальные функции быстрее компилируются, лучше читаются сообщения об ошибках, код обобщённого алгоритма компилируется только один раз и поэтому бинарник получается компактнее
Статический полиморфизм на шаблонах быстрее исполняется (если только бинарник не раздуется слишком сильно), причём чем универсальнее алгоритм, тем важнее это преимущество. И наоборот — в бизнес-логике где у тебя конкретные классы, в "обобщённый алгоритм" передаются довольно тяжеловесные функции, для которых вызов по указателю не скажется на скорости хоть сколько-нибудь заметно. Поэтому если не пишешь что-то мегауниверсальное, то лучше виртуальными функциями сделать. На деле доходит до смешного, когда какая-нибудь популярная библиотека для сериализации в json принимаев на вход в шаблон какой-нибудь template<typename Handler>, который может быть сериализатором-в-строку-без-пробелов, сериализатором-в-строку-с-пробелами, сериализатором-в-файл-без-пробелов итд и всё это разные классы, и в итоге пишется много хедер-онли говна с шаблонами, которые в случае опечатки высирают в консоль бредовое эссе. Ну нахрена, что за шиза?
Нет такой подлости и мерзости, на которую бы не пошёл gcc ради бессмысленных 5% скорости в никому не нужном синтетическом тесте
Re: Об эффективности виртуальных функций
От: cppguard  
Дата: 07.08.24 10:34
Оценка: +2
Здравствуйте, Евгений Музыченко, Вы писали:

ЕМ>Все эти люди старательно избегали любой косвенности, указатели/ссылки использовали лишь в самых крайних случаях?


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


Программисты на С++ в погоне за мифической оптимизацией очень похожи на владельцев дорогих автомобилей, которые не могут найти 100р на парковку.
Re: Об эффективности виртуальных функций
От: Sergey_BG Россия  
Дата: 07.08.24 15:52
Оценка:
Здравствуйте, Евгений Музыченко, Вы писали:

Написал небольшой пример. Вариант когда класс B final работает в 10 раз быстрее.

#include <algorithm>
#include <chrono>
#include <iostream>
#include <memory>
#include <numeric>
#include <vector>

class IIntInterface
{
public:
  virtual int getInt() const = 0;
};

class A : public IIntInterface
{
public:
  int getInt() const override { return 1; }
};

class B: public A
{
public:
  int getInt() const override { return 2; }
};

int main()
{
    std::vector<std::unique_ptr<B>> data;
    constexpr int COUNT = 1024 * 1024;
    data.reserve(COUNT);

    for (int i = 0; i < COUNT; ++i)
      data.push_back(std::make_unique<B>());

    const auto start = std::chrono::high_resolution_clock::now();
    const auto result = std::accumulate(data.begin(), data.end(), 0, [](int a, auto& b)->int { return a + b->getInt(); });
    const auto end = std::chrono::high_resolution_clock::now();
    const auto duration = std::chrono::duration_cast<std::chrono::microseconds>(end - start);
    std::cout << "Time " << duration.count() << "Result: " << result << std::endl;

    system("pause");
}
Сергей
Re[2]: Об эффективности виртуальных функций
От: ВеликийРеверс google
Дата: 07.08.24 15:56
Оценка:
на реддите была статейка
народ тестировал final на больших проектах
замеры сказали что final это плохо
Re[2]: Об эффективности виртуальных функций
От: kov_serg Россия  
Дата: 07.08.24 16:02
Оценка: +1 :)
Здравствуйте, Sergey_BG, Вы писали:

S_B>Написал небольшой пример. Вариант когда класс B final работает в 10 раз быстрее.

Это всё фигня. В C++ бесконечный цикл работает вообще мгновенно
Re[2]: Об эффективности виртуальных функций
От: ВеликийРеверс google
Дата: 07.08.24 16:07
Оценка:
нашел
https://16bpp.net/blog/post/the-performance-impact-of-cpp-final-keyword/
Re[3]: Об эффективности виртуальных функций
От: Sergey_BG Россия  
Дата: 07.08.24 18:55
Оценка:
Здравствуйте, ВеликийРеверс, Вы писали:
ВР>замеры сказали что final это плохо

Я написал про финал не для его рекламы, а чтоб показать, что вызов виртуального метода, и не виртуального, это разные вещи, а не просто два джампа или один.
Сергей
Re: Об эффективности виртуальных функций
От: Pzz Россия https://github.com/alexpevzner
Дата: 07.08.24 19:29
Оценка: +1
Здравствуйте, Евгений Музыченко, Вы писали:

ЕМ>Всю жизнь был уверен, что оценки вроде "виртуальные функции сильно снижают быстродействие" идут от неграмотных гуманитариев, которые где-то слышали звон, а потом рожают на его основе заумные тексты, которые потом цитируют технари, совершенно незнакомые с языком. Но почитал описании истории языка от Страуструпа (я читал несколько его книг, но истории раньше почему-то не попадалось), где он пишет, что многим программистам, в том числе системным, "было трудно поверить в то, что виртуальные функции могут быть достаточно быстрыми".


Когда ядро UNIX написали на Си, а не на ассемблере, как положено, и все крутили пальцем у виска, Роберт Пайк врал на голубом глазу, что ихний Си по скорости в среднем не уступает асму. В реальности он уступал в два раза, но сейчас про то никто не помнит, а ядра ОС считается само собой разумеющимся писать на Си.

Интересно, что Пайк потом повторил этот трюк, рассказав всем, что евонный Go в среднем такой же быстрый, как Си. В реальности проигрывает раза в два, но вряд ли это запомнят.

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

ЕМ>Откуда вообще могло взяться такое опасение в профессиональной-то среде? Ведь каждый системщик должен знать, что в любой ОС тьма косвенных вызовов, начиная от обработчиков прерываний, точек входа в драйверы ядра, внутренних служб ядра, и заканчивая всякими обработчиками событий и системными услугами "высокого уровня". Все это вызывается до тысяч раз в секунду, и я не помню, чтоб кто-то переживал по поводу самого факта косвенности вызова, ибо затраты на него ничтожны на фоне полезной работы любого кода.


Если ты вызываешь обработчик прерываний по указателю или как виртуальную функцию, то на фоне цены обработки прерывания твой косвенный вызов никто и не заметит.

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

Всему свое место и вопросы эффективности всегда существуют в контексте, а не абстрактным сферическим конём в вакууме.
Re[3]: Об эффективности виртуальных функций
От: Pzz Россия https://github.com/alexpevzner
Дата: 07.08.24 19:34
Оценка: +2
Здравствуйте, Евгений Музыченко, Вы писали:

ЕМ>В те времена, когда одно-два обращения к памяти занимали микросекунды, "суровый реалтайм" даже не помышляли писать даже на C, не говоря уже о C++.


Суровый реалтайм — это про гарантии приехать вовремя, а не про абсолютную величину этого времени.

Мне приходилось писать суровый риалтайм для 8-битной атмеловской однокристалки. Сначала, как дурак, написал на асме, но просчитался с алгоритмом, и правильно не заработало. Потом время стало поджимать, и я "смакетировал" следущую версию алгоритна на Си. И он хорошо заработал, поэтому в таком виде в дело и пошло.
Re[8]: Об эффективности виртуальных функций
От: Pzz Россия https://github.com/alexpevzner
Дата: 07.08.24 19:45
Оценка: +1
Здравствуйте, пффф, Вы писали:

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


Я очень редко упарываюсь по оптимизации, но у меня обычно все сразу достаточно быстро работает. Но я не делаю очевидных глупостей, типа считать strlen() строки в цикле, который много раз использует одну и ту же строку (хотя с современным компилятором это, наверное, сойдет с рук) и использования квадратичных алгоритмов там, где существуют алгоритмы N * Log(N) или лучше.

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

Я, кстати, Go-шечник еще, а не только Сишечник.
Re[9]: Об эффективности виртуальных функций
От: Pzz Россия https://github.com/alexpevzner
Дата: 07.08.24 19:47
Оценка: +1
Здравствуйте, Евгений Музыченко, Вы писали:

ЕМ>Вот сколько плюсовиков, работающих у вас с современными 32-разрядными МК, где сотни мегагерц и хотя бы сотни килобайт, смогут написать что-нибудь годное для 8-разрядного, где 5-10 МГц и единицы килобайт?


Зато у 8-битных контроллеров память одинаково быстро (или одинаково медленно) работает, хоть вдоль ее читай, хоть поперек. Что не скажешь про современные 32-битные, с динамической памятью, кешом, предвыборкой и отложенной записью.
Re[2]: Об эффективности виртуальных функций
От: T4r4sB Россия  
Дата: 07.08.24 19:57
Оценка: :))
Здравствуйте, cppguard, Вы писали:

C>Программисты на С++ в погоне за мифической оптимизацией очень похожи на владельцев дорогих автомобилей, которые не могут найти 100р на парковку.


Отлично, я себе подпись придумал
Нет такой подлости и мерзости, на которую бы не пошёл gcc ради бессмысленных 5% скорости в никому не нужном синтетическом тесте
Re[15]: Об эффективности виртуальных функций
От: Pzz Россия https://github.com/alexpevzner
Дата: 07.08.24 19:58
Оценка: +1
Здравствуйте, Евгений Музыченко, Вы писали:

П>>Я, как минимум, написал один HTTP-сервер на сишечке


ЕМ>Это считается сложным проектом для C? Не знал, честно. Вот, например, Simple HTTP Server — цельных 25 килобайт исходник. Или Ваш был сильно круче?


Очень зависит от функциональности. Можно строк в 300 уложиться, и оно даже будет формально соблюдать HTTP/1.0 и уметь правильно отвечать на GET. А можно понакрутить всякого разного, как в Apache или Nginx.

В HTTP много нюансов, которые не всегда обязательно реализовывать, но если уж реализовывать, там как надо набегает.
Re[15]: Об эффективности виртуальных функций
От: Pzz Россия https://github.com/alexpevzner
Дата: 07.08.24 20:09
Оценка:
Здравствуйте, B0FEE664, Вы писали:

S>>Скорее Go, Java и C#, возможно где-то и Rust.

BFE>Не-а. C. Большинство бесплатных проектов на C. Тот же Linux.

Linux — ядро или linux — операционная система?

Если говорить про операционную систему, а не только про ядро, там много-много всякого кода на разных языках. И ядро — далеко не самый большой кусок. Кажется, в одном гуглохроме столько кода, что на целую ОСь хватит. На гуглохроме даже ctags ломается. И весь этот код не на Cи
Re[3]: Об эффективности виртуальных функций
От: VVV Россия  
Дата: 07.08.24 20:35
Оценка: 3 (1)
Здравствуйте, ВеликийРеверс, Вы писали:

ВР>нашел

ВР>https://16bpp.net/blog/post/the-performance-impact-of-cpp-final-keyword/

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

#include <iostream>
#include <chrono>

using namespace std::chrono;

class Base
{
public:
    virtual void Test(){}
    virtual void Reset(){}
    virtual unsigned GetI() const { return 1u; }
};

class NoFinal : public Base
{
    unsigned i = 0;
public:
    virtual void Test() override 
    {
        ++i;
    }
    virtual void Reset(){ i = 0; }
    virtual unsigned GetI() const { return i; }
};

class Final final : public Base
{
    unsigned i = 0;
public:
    virtual void Test() final 
    {
        ++i;
    }
    void TestNoVirt() // << добавлена, чтобы посмотреть, как будет работать невиртуальная функция
    {
        ++i;
    }
    virtual void Reset(){ i = 0; }
    virtual unsigned GetI() const { return i; } // << пришлось завести взятие i, чтобы оптимизатор не выкидывал вызовы
};

#define COUNT (1024 * 1024 * 1024)

void TestB(Base* b)
// void TestB(NoFinal* b) // << даже если поставить так, всё равно вызывается через таблицу виртуальных функций
{
    b->Reset();

    auto start = steady_clock::now();
    for (unsigned i = 0; i < COUNT; i++)
    {
        b->Test();
    }
    auto end = steady_clock::now();
    auto elapsed = duration_cast<milliseconds>(end - start);

    std::cout << "TestB = " << elapsed.count() << " i=" << b->GetI() << "\n";
}

void TestF(Final* f)
{
    f->Reset();

    auto start = steady_clock::now();
    for (unsigned i = 0; i < COUNT; i++)
    {
        f->Test();
    }
    auto end = steady_clock::now();
    auto elapsed = duration_cast<milliseconds>(end - start);

    std::cout << "TestF = " << elapsed.count() << " i=" << f->GetI() << "\n";
}

void TestNoVirt(Final* f)
{
    f->Reset();

    auto start = steady_clock::now();
    for (unsigned i = 0; i < COUNT; i++)
    {
        f->TestNoVirt();
    }
    auto end = steady_clock::now();
    auto elapsed = duration_cast<milliseconds>(end - start);

    std::cout << "TestNoVirt = " << elapsed.count() << " i=" << f->GetI() <<"\n";
}

int main(int argc, char** argv)
{
    // Base* b = new NoFinal;
    NoFinal* b = new NoFinal;

    Final* f = new Final;

    TestNoVirt(f);

    TestB(b);

    TestF(f);

    delete f;

    delete b;

    return 0;
}


результаты
g++ -O0 main.cpp -o main
TestNoVirt = 1843 i=1073741824
TestB = 2109 i=1073741824
TestF = 1899 i=1073741824 << даже без оптимизации быстрее где-то на 10%

g++ -O1 main.cpp -o main
TestNoVirt = 260 i=1073741824
TestB = 1254 i=1073741824
TestF = 254 i=1073741824 << уже намного быстрее

g++ -O2 main.cpp -o main
TestNoVirt = 0 i=1073741824
TestB = 1241 i=1073741824
TestF = 0 i=1073741824 << компилер сам всё посчитал в компайлтайме! — очень быстро в рантвйме)

g++ -O3 main.cpp -o main
TestNoVirt = 0 i=1073741824
TestB = 1249 i=1073741824 << через таблицу виртуальных функций — не очень-то оптимизируется
TestF = 0 i=1073741824

g++ -Ofast main.cpp -o main
TestNoVirt = 0 i=1073741824
TestB = 1245 i=1073741824
TestF = 0 i=1073741824

clang++ -O3 main.cpp -o mainclang
./mainclang
TestNoVirt = 0 i=1073741824
TestB = 1262 i=1073741824
TestF = 0 i=1073741824

Вывод: final даёт хорошую оптимизацию, если может сработать на этапе компиляции.
Re[4]: Об эффективности виртуальных функций
От: ВеликийРеверс google
Дата: 07.08.24 20:47
Оценка: -1
сколько людей
столько и мнений

да final работает на этапе компиляции
если компилер может вывести виртуальную функцию
он может заинлайнить

и насколько я понял ту статью
то когда вместо виртуальной функции инлайнится полностью функция
то перфоменс падает

короче виртуальные функции это не есть плохо
Re[5]: Об эффективности виртуальных функций
От: Кодт Россия  
Дата: 07.08.24 21:44
Оценка: 1 (1) +3
Здравствуйте, Евгений Музыченко, Вы писали:

N>>Восемь лишних байт на класс в каждом экземпляре.


ЕМ>Если объектов единицы-десятки миллионов, и в каждом до десятков байт, то можно обойтись и 32-разрядными адресами, это будет по четыре байта. Если в объекте сорок байт, то четыре байта — 10%. Это считается много?


А если содержательная часть объекта — пара-тройка байтов, то +8 байтов на указатель +5-6 байтов на выравнивание оказывается уже что-то дохрена много.
Особенно, когда у тебя миллионы таких объектов.

Высокочастотники очень упарываются за производительность, там битва за то, чтобы в линейку кеша всё влезало, например.
Лишние 8 байтов в объекте — и хоба, например, размер объекта не кратный линейке кеша (или наоборот). И в массиве объектов начинаются кешмиссы.

Объект с vfptr перестаёт быть тривиально конструируемым. Его нельзя просто разместить и оставить с мусором, его нельзя просто обнулить.
Как минимум одно поле в нём инициализируется не нулём. А это тоже времечко.
Перекуём баги на фичи!
Re[2]: Об эффективности виртуальных функций
От: пффф  
Дата: 07.08.24 23:24
Оценка: :)
Здравствуйте, Pzz, Вы писали:

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


Тогда кеша не было
Re[3]: Об эффективности виртуальных функций
От: Pzz Россия https://github.com/alexpevzner
Дата: 07.08.24 23:27
Оценка: +1
Здравствуйте, пффф, Вы писали:

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


П>Тогда кеша не было


Минеточку. Кеш даже и на VAX-е уже был, если верить википедии.
Re[4]: Об эффективности виртуальных функций
От: пффф  
Дата: 07.08.24 23:37
Оценка:
Здравствуйте, Pzz, Вы писали:

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


П>>Тогда кеша не было


Pzz>Минеточку. Кеш даже и на VAX-е уже был, если верить википедии.


Сколько там того кеша... Несколько кило...

Сколько кеша было на 286?

Intel 486 имел расположенную на кристалле кэш-память объёмом 8 Кбайт, позднее — 16 Кбайт, работающую на частоте ядра.


Но да, в принципе, даже наличие пары байт кеша уже позволяет врать
Re[5]: Об эффективности виртуальных функций
От: Pzz Россия https://github.com/alexpevzner
Дата: 07.08.24 23:39
Оценка:
Здравствуйте, пффф, Вы писали:

Pzz>>Минеточку. Кеш даже и на VAX-е уже был, если верить википедии.


П>Сколько там того кеша... Несколько кило...


Так когда кыша мало, особенно важно кучно по нему попадать.
Re[18]: Об эффективности виртуальных функций
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 08.08.24 09:06
Оценка:
Здравствуйте, so5team, Вы писали:

S>один из самых активно используемых и проверенных в продакшене парсеров HTTP протокола, llhttp, имеет реализацию ~300Kb.


Что изменилось бы, окажись там 300 Мб?

S>И если вы находите какое-то говно в 200 строк, то это всего лишь означает до нормальной поддержки HTTP там как до Луны.


Кто говорил о "нормальной" поддержке? Я не говорил. И Марти не говорил. Его вообще никто за язык не тянул, он привел свой HTTP-сервер, как пример того, что он "умеет писать на C" (а я, соответственно, не умею, коли своего сервера не писал).
Re[15]: Об эффективности виртуальных функций
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 08.08.24 09:15
Оценка:
Здравствуйте, so5team, Вы писали:

S>неявное приведение от int к bool или к float -- это не ошибка с точки зрения языка. Это легальная операция.


Осталось выяснить, есть ли какой-то смысл упорно поддерживать ее легальность. Кому это неявное приведение сколько-нибудь заметно помогает? Я еще понимаю, когда сишники бухтят на всякие reinterpret_cast, в которых буковок больше, чем в паре скобок, ну так сишники и привыкли писать предельно лаконично. А когда плюсовики, привыкшие городить изрядные объемы кода для решения простейших задач, возбуждаются на то, что им придется добавить десяток-другой, или даже сотню, явных приведений — не понимаю.

S>Да, C++ печально известен этим качеством.


И при всем этом, на весь стандарт до сих пор меньше двух десятков рекомендаций о выдаче предупреждения. Каждый разработчик компилятора по-своему решает, о чем предупреждать, а о чем промолчать.
Re[12]: Об эффективности виртуальных функций
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 08.08.24 09:17
Оценка:
Здравствуйте, B0FEE664, Вы писали:

BFE>В рамках языка C++ нет смысла делать что-то большее.


В рамках любого языка всегда есть смысл дать программе возможность получить от компилятора то, что ему заведомо известно, без приседаний и трюков.
Re[15]: Об эффективности виртуальных функций
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 08.08.24 09:21
Оценка:
Здравствуйте, B0FEE664, Вы писали:

BFE>Nginx написан на C и используется повсеместно.


Вот хороший пример, кстати. Что мешало написать его на C++, увеличив надежность, облегчив модификацию и расширяемость, и не потеряв при этом "ни байта, ни такта"?
Re[3]: Об эффективности виртуальных функций
От: B0FEE664  
Дата: 08.08.24 09:21
Оценка:
Здравствуйте, kov_serg, Вы писали:

_>Это всё фигня. В C++ бесконечный цикл работает вообще мгновенно

Уже нет.
И каждый день — без права на ошибку...
Re[2]: Об эффективности виртуальных функций
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 08.08.24 09:26
Оценка:
Здравствуйте, Sergey_BG, Вы писали:

S_B>Написал небольшой пример. Вариант когда класс B final работает в 10 раз быстрее.


Если задаться целью написать подходящий пример, то я могу сделать разницу и на два порядка. Речь-то не о крайних показательных примерах, а об общем случае.
Re[2]: Об эффективности виртуальных функций
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 08.08.24 09:39
Оценка:
Здравствуйте, Pzz, Вы писали:

Pzz>Когда ядро UNIX написали на Си, а не на ассемблере, как положено, и все крутили пальцем у виска


На самом деле на C написали только относительно "медленные" части кода, а то, что требовало предельной эффективности, таки писали на ассемблере.

Pzz>Роберт Пайк врал на голубом глазу, что ихний Си по скорости в среднем не уступает асму. В реальности он уступал в два раза


Ну да, оптимизации тогда, считай, и не было.

Pzz>но сейчас про то никто не помнит, а ядра ОС считается само собой разумеющимся писать на Си.


Так ситуация с оптимизацией давно поменялась — уже где-то в начале-середине 90-х код получался радикально лучше, а экономить единичные байты и такты уже давно не требовалось. Примерно с середины 90-х ядра ОС можно было писать на C++, получая ту же самую эффективность, что и на C.

Pzz>Интересно, что Пайк потом повторил этот трюк, рассказав всем, что евонный Go в среднем такой же быстрый, как Си. В реальности проигрывает раза в два, но вряд ли это запомнят.


Да, я тоже впечатлился восторженными рассказами о Go, почитал описания, и понял, что таким же быстрым он быть не может. Но может быть быстрее "полуинтерпретируемых" Java/C#, и уж точно быстрее питона.

Pzz>А Страус просто честный очень.


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

Pzz>Если ты вызываешь обработчик прерываний по указателю или как виртуальную функцию, то на фоне цены обработки прерывания твой косвенный вызов никто и не заметит.


Именно. И обработчик прерывания физически невозможно вызвать не косвенно.

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


Верно. Но я поднял вопрос именно из-за того, что нередко вижу утверждения о "медленности" виртуальных функций как раз без контекста. "Медленные, и все".
Re[16]: Об эффективности виртуальных функций
От: пффф  
Дата: 08.08.24 09:44
Оценка: +1
Здравствуйте, Евгений Музыченко, Вы писали:

BFE>>Nginx написан на C и используется повсеместно.


ЕМ>Вот хороший пример, кстати. Что мешало написать его на C++, увеличив надежность, облегчив модификацию и расширяемость, и не потеряв при этом "ни байта, ни такта"?


Автор — админ, он сишечку-то с трудом осилил
Re[6]: Об эффективности виртуальных функций
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 08.08.24 09:48
Оценка:
Здравствуйте, Кодт, Вы писали:

К>если содержательная часть объекта — пара-тройка байтов


То это, скорее всего, и не объект вовсе, а простая структура, и навешивать на него виртуальные методы вряд ли имеет смысл.

К>то +8 байтов на указатель


Меня прям умиляет, как народ начал совершенно автоматически мыслить 64-разрядными архитектурами по умолчанию. Задачи, укладывающиеся в 32-разрядные, уже кончились?

К>Высокочастотники очень упарываются за производительность, там битва за то, чтобы в линейку кеша всё влезало, например.


Значит, это просто не их случай, и всего делов. Если Вы где-то в моих словах увидели призыв тащить виртуальные функции везде и всюду, то покажите пальцем.
Re[4]: Об эффективности виртуальных функций
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 08.08.24 09:51
Оценка:
Здравствуйте, Pzz, Вы писали:

Pzz>Кеш даже и на VAX-е уже был


Простейшие кэши стали делать еще в 60-е.
Re[19]: Об эффективности виртуальных функций
От: so5team https://stiffstream.com
Дата: 08.08.24 10:32
Оценка: :)
Здравствуйте, Евгений Музыченко, Вы писали:

S>>один из самых активно используемых и проверенных в продакшене парсеров HTTP протокола, llhttp, имеет реализацию ~300Kb.


ЕМ>Что изменилось бы, окажись там 300 Мб?


Увеличилась бы вероятность, что там не говно.

S>>И если вы находите какое-то говно в 200 строк, то это всего лишь означает до нормальной поддержки HTTP там как до Луны.


ЕМ>Кто говорил о "нормальной" поддержке?


Ну если вам достаточно хз чего, а не нормального сервера с нормальной обработкой HTTP, то вопросов нет.
Re[16]: Об эффективности виртуальных функций
От: so5team https://stiffstream.com
Дата: 08.08.24 10:35
Оценка: :)
Здравствуйте, Евгений Музыченко, Вы писали:

S>>неявное приведение от int к bool или к float -- это не ошибка с точки зрения языка. Это легальная операция.


ЕМ>Осталось выяснить, есть ли какой-то смысл упорно поддерживать ее легальность.


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

Ну вот выясните вы, что смысла поддерживать ее легальность нет. И что?

В очередной раз позвиздите на RSDN и все?
Re[20]: Об эффективности виртуальных функций
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 08.08.24 10:37
Оценка:
Здравствуйте, so5team, Вы писали:

ЕМ>>Что изменилось бы, окажись там 300 Мб?


S>Увеличилась бы вероятность, что там не говно.


А если 3 Гб, то еще бы увеличилась?

S>Ну если вам достаточно хз чего, а не нормального сервера с нормальной обработкой HTTP, то вопросов нет.


У Вас, судя во всему, ко мне "такой личный неприязнь", что хочется хоть как-нибудь, да задеть. Только меня-то не задевает, так чего ради эты мелочные укусы?
Re[10]: Об эффективности виртуальных функций
От: andyp  
Дата: 08.08.24 10:55
Оценка:
Здравствуйте, karbofos42, Вы писали:

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


Все наоборот как раз. Итератор — эта всё что нужно знать алгоритму о твоей коллекция без лишней требухи. В нем оставлено от коллекции только то, как по ней итерировать.
Создать его нужно один раз на все итерации. Это хорошая абстракция, так как помогла разделить алгоритмы и коллекции (контейнеры по плюсовому. хотя по нормальному в CS есть термин структуры данных). А коллекция твоя — плохая абстракция, так как нарушает SRP(https://en.wikipedia.org/wiki/Single-responsibility_principle) — в ней и менеджмент памяти и доступ к элементам, хотя это две разделяемые сущности. Особенно это хорошо видно, когда требуется обходить структуру данных в разных порядках.
Re[21]: Об эффективности виртуальных функций
От: so5team https://stiffstream.com
Дата: 08.08.24 11:12
Оценка: :)
Здравствуйте, Евгений Музыченко, Вы писали:

ЕМ>>>Что изменилось бы, окажись там 300 Мб?


S>>Увеличилась бы вероятность, что там не говно.


ЕМ>А если 3 Гб, то еще бы увеличилась?


Уменьшилась бы, маятник бы качнулся в другую сторону.

S>>Ну если вам достаточно хз чего, а не нормального сервера с нормальной обработкой HTTP, то вопросов нет.


ЕМ>У Вас, судя во всему, ко мне "такой личный неприязнь", что хочется хоть как-нибудь, да задеть. Только меня-то не задевает, так чего ради эты мелочные укусы?


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

Так что когда есть возможность макнуть вас в ваши же испражнения, то это стоит сделать хотя бы для того, чтобы никто не подумал "о, ну раз у человека 30+ лет опыта на C++, то он стоящие вещи говорит".
Re[7]: Об эффективности виртуальных функций
От: Nuzhny Россия https://github.com/Nuzhny007
Дата: 08.08.24 11:27
Оценка:
Здравствуйте, Евгений Музыченко, Вы писали:

ЕМ>Меня прям умиляет, как народ начал совершенно автоматически мыслить 64-разрядными архитектурами по умолчанию. Задачи, укладывающиеся в 32-разрядные, уже кончились?


Я ещё лет 10 назад заметил, что моя программа собранная под 32 бит работает на 64бит ОС медленнее, чем собранная под 64 бит. Причину не расследовал (наверное, потому что адреса всё равно транслируются в 64 бита?), но сложилось устойчивое впечатление, что мучать старушку не следует.
Re[4]: Об эффективности виртуальных функций
От: Философ Ад http://vk.com/id10256428
Дата: 08.08.24 11:31
Оценка:
Здравствуйте, B0FEE664, Вы писали:

_>>Это всё фигня. В C++ бесконечный цикл работает вообще мгновенно

BFE>Уже нет.

О! Интересно!
А давно? Почему перестал?
Всё сказанное выше — личное мнение, если не указано обратное.
Re[7]: Об эффективности виртуальных функций
От: пффф  
Дата: 08.08.24 11:33
Оценка:
Здравствуйте, Евгений Музыченко, Вы писали:


ЕМ>Меня прям умиляет, как народ начал совершенно автоматически мыслить 64-разрядными архитектурами по умолчанию. Задачи, укладывающиеся в 32-разрядные, уже кончились?


Прикинь, данные больших объемов гораздо удобнее обрабатывать на 64х разрядных системах
Re[3]: Об эффективности виртуальных функций
От: Pzz Россия https://github.com/alexpevzner
Дата: 08.08.24 11:43
Оценка:
Здравствуйте, Евгений Музыченко, Вы писали:

ЕМ>Да, я тоже впечатлился восторженными рассказами о Go, почитал описания, и понял, что таким же быстрым он быть не может. Но может быть быстрее "полуинтерпретируемых" Java/C#, и уж точно быстрее питона.


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

Но интересно, что это вот утверждение, что язык XXX в два раза проирывает по производительности Си, периодически упоминается в контексте разных "полуинтерпретируемых" языков. Таких как Java/JS/Go.

Кажется удивительным, что компилируемый Go оказывается в той же лиге, что и JS. Но если вдуматься, компилятор Go такой же быстрый и наивный, как TurboC 2.0, а в производительность JS и Java очень сильно вкладывались.

Компилятор Go когда-то был написан на Си. Потом его переписали на самом Go, причем нодмально так перенесли, по-Пайковски. Пайк написал перекомпилятор C в Go, добился того, что выхлоп перекомпилированного компилятора байт-в-байт совпадает с выхлопом оригинального, а потом местами подчистил руками.

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

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

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


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


Ну медленные и медленные. Пусть конкуренты пишут быстрый код, а мы пока делом займемсе
Re[8]: Об эффективности виртуальных функций
От: Философ Ад http://vk.com/id10256428
Дата: 08.08.24 11:47
Оценка:
Здравствуйте, Nuzhny, Вы писали:

N>Я ещё лет 10 назад заметил, что моя программа собранная под 32 бит работает на 64бит ОС медленнее, чем собранная под 64 бит. Причину не расследовал (наверное, потому что адреса всё равно транслируются в 64 бита?), но сложилось устойчивое впечатление, что мучать старушку не следует.


У меня под столом стоит мой старенький C2 Duo E8400. На котором я когда-то выяснил, что моя софтина собранная на x86 работает быстрее, чем на x64. Я долгое время прям твёрдо был в этом убеждён.
Когда купил i9-11900kf, то в какой-то момент прогнал — та же софтина работала одинаково в обеих вариантах. Немного копнул — оказалось, что стоимость вызова функции на x64 ниже. Помогла большая насмотренность на трэйсы от dotTrace. К несчастью до детального сравнения обоих вариантов руки так и не дошли.
Может быть когда-нибудь дойдут: E8400 всё ещё жив....
Всё сказанное выше — личное мнение, если не указано обратное.
Re[8]: Об эффективности виртуальных функций
От: Философ Ад http://vk.com/id10256428
Дата: 08.08.24 11:50
Оценка:
Здравствуйте, пффф, Вы писали:

П>Прикинь, данные больших объемов гораздо удобнее обрабатывать на 64х разрядных системах


оч. сильно зависит от того, что понимается под обработкой. Если приходится большие файлы на память мапить — да, безусловно. Если читаешь кусочками по 4кб — пофигу.
Всё сказанное выше — личное мнение, если не указано обратное.
Re[22]: Об эффективности виртуальных функций
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 08.08.24 11:54
Оценка:
Здравствуйте, so5team, Вы писали:

ЕМ>>>>Что изменилось бы, окажись там 300 Мб?

S>>>Увеличилась бы вероятность, что там не говно.
ЕМ>>А если 3 Гб, то еще бы увеличилась?

S>Уменьшилась бы, маятник бы качнулся в другую сторону.


Какими критериями оценки Вы пользуетесь, делая подобные выводы?

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


Ну так ограничьтесь прямыми претензиями по делу, как Вы это обычно делаете. Я ж не против. А когда Вы начинаете поминать меня не к месту, или додумывать, чего мне якобы достаточно, то сводите предметную дискуссию к банальной перепалке в стиле "а ты кто такой".
Re[8]: Об эффективности виртуальных функций
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 08.08.24 11:56
Оценка:
Здравствуйте, Nuzhny, Вы писали:

N>Я ещё лет 10 назад заметил, что моя программа собранная под 32 бит работает на 64бит ОС медленнее, чем собранная под 64 бит. Причину не расследовал


А стоило бы.

N>наверное, потому что адреса всё равно транслируются в 64 бита?


Аппаратно процессор работает с той же скоростью. А вот те же системные вызовы, понятное дело, идут через переходники. Если они составляют заметную долю всей работы, то это скажется на быстродействии. Если же основную долю составляют вычисления, то нет.
Re[8]: Об эффективности виртуальных функций
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 08.08.24 11:59
Оценка:
Здравствуйте, пффф, Вы писали:

П>Прикинь, данные больших объемов гораздо удобнее обрабатывать на 64х разрядных системах


Да, я где-то об этом слышал. Но во многих случаях 64-разрядные сборки выпускают просто потому, что они "нативные", хотя ощутимого преимущества это не дает, и больше услаждает взоры тех, кто полагает, будто 64-разрядное приложение само по себе лучше 32-разрядного.
Re[9]: Об эффективности виртуальных функций
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 08.08.24 12:02
Оценка:
Здравствуйте, Философ, Вы писали:

Ф>оч. сильно зависит от того, что понимается под обработкой. Если приходится большие файлы на память мапить — да, безусловно. Если читаешь кусочками по 4кб — пофигу.


Всякие разреженные данные сильно удобнее обрабатывать в большом адресном пространстве. Но это частные случаи, не мейнстрим.
Re[23]: Об эффективности виртуальных функций
От: so5team https://stiffstream.com
Дата: 08.08.24 12:08
Оценка: :)
Здравствуйте, Евгений Музыченко, Вы писали:

ЕМ>Какими критериями оценки Вы пользуетесь, делая подобные выводы?


Гадаю на кофейной гуще, конечно же.

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


ЕМ>Ну так ограничьтесь прямыми претензиями по делу, как Вы это обычно делаете.


Евгений, вы не можете ни в конкретику, ни в конструктивный разговор. Поэтому и приходится вешать на ваши высказывания ярлык "Так это ж Музыченко, что ж вы хотели то?"
Re[24]: Об эффективности виртуальных функций
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 08.08.24 12:14
Оценка:
Здравствуйте, so5team, Вы писали:

S>вы не можете ни в конкретику, ни в конструктивный разговор.


Я высказываю достаточно и конкретики, и конструктивных предложений, но Вы каждый раз требуете конкретных примеров кода, детально проработанных предложений для комитета, и подобного. Это не означает "не можете", это означает, что Вы просто ожидаете более высокого уровня конкретики, чем я согласен дать в той или иной теме.
Re[25]: Об эффективности виртуальных функций
От: so5team https://stiffstream.com
Дата: 08.08.24 12:23
Оценка: :)
Здравствуйте, Евгений Музыченко, Вы писали:

S>>вы не можете ни в конкретику, ни в конструктивный разговор.


ЕМ>Я высказываю достаточно и конкретики, и конструктивных предложений


Достаточно для кого? Полагаю, что для вас самих. Но вы-то здесь не с самим собой диалог ведете.

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


Это и называется "вы не можете ни в конкретику, ни в конструктивный разговор".
Re[11]: Об эффективности виртуальных функций
От: karbofos42 Россия  
Дата: 08.08.24 12:50
Оценка:
Здравствуйте, andyp, Вы писали:

A>Все наоборот как раз. Итератор — эта всё что нужно знать алгоритму о твоей коллекция без лишней требухи. В нем оставлено от коллекции только то, как по ней итерировать.

A>Создать его нужно один раз на все итерации. Это хорошая абстракция, так как помогла разделить алгоритмы и коллекции (контейнеры по плюсовому. хотя по нормальному в CS есть термин структуры данных).

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

A>А коллекция твоя — плохая абстракция, так как нарушает SRP(https://en.wikipedia.org/wiki/Single-responsibility_principle) — в ней и менеджмент памяти и доступ к элементам, хотя это две разделяемые сущности. Особенно это хорошо видно, когда требуется обходить структуру данных в разных порядках.


Значит и коллекции из STL плохие. Тот же вектор даёт доступ к элементам по индексу, а должен был делегировать эти тайные знания итераторам.
Re[13]: Об эффективности виртуальных функций
От: B0FEE664  
Дата: 08.08.24 13:00
Оценка:
Здравствуйте, Евгений Музыченко, Вы писали:

BFE>>В рамках языка C++ нет смысла делать что-то большее.

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

В рамках контекста "задачу создания таблиц строк вида "длина+текст" это все равно не решает, приходится извращаться, как и раньше" я не понимаю о чём вы пишите.
И каждый день — без права на ошибку...
Re[5]: Об эффективности виртуальных функций
От: B0FEE664  
Дата: 08.08.24 13:08
Оценка:
Здравствуйте, Философ, Вы писали:

_>>>Это всё фигня. В C++ бесконечный цикл работает вообще мгновенно

BFE>>Уже нет.
Ф>О! Интересно!
Ф>А давно? Почему перестал?
Это C++26 core language features
здесь
И каждый день — без права на ошибку...
Re[14]: Об эффективности виртуальных функций
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 08.08.24 15:22
Оценка:
Здравствуйте, B0FEE664, Вы писали:

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


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

А ведь научить компилятор непосредственно отдавать любую информацию, которая у него есть, совсем просто. Но делать это предпочитают по капле, и лишь в редких случаях непосредственно, чаще — лишь косвенно.
Re[15]: Об эффективности виртуальных функций
От: B0FEE664  
Дата: 08.08.24 15:51
Оценка:
Здравствуйте, Евгений Музыченко, Вы писали:

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

ЕМ>О том, что длина литеральной строки — лишь один из видов информации о программе, известной компилятору, но добываемой не всегда очевидно.
Вот как читателю догадаться, что вы пишите именно об этом, а не о массиве BSTR строк?

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

Строка и есть массив, хотя я не помню как давно (собирается с -std=c++98):
struct StrSz
{
   std::size_t m_sz;
   const char* m_str;
   template<std::size_t N>
   StrSz(const char (&str)[N])
     : m_sz(N),
       m_str(str)
   {
   }
};

    StrSz strSz = StrSz("asdf");
    std::cout << "sz of \"" << strSz.m_str << "\" is "<< strSz.m_sz << std::endl;

sz of "asdf" is 5

ЕМ>А ведь научить компилятор непосредственно отдавать любую информацию, которая у него есть, совсем просто. Но делать это предпочитают по капле, и лишь в редких случаях непосредственно, чаще — лишь косвенно.

Просто или нет, но ведёт к изменению синтаксиса.
И каждый день — без права на ошибку...
Re[16]: Об эффективности виртуальных функций
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 08.08.24 16:05
Оценка:
Здравствуйте, B0FEE664, Вы писали:

BFE>Вот как читателю догадаться, что вы пишите именно об этом, а не о массиве BSTR строк?


Я упоминал детали по ходу обсуждения. Но да, тема уже раздулась неприлично.

BFE>собирается с -std=c++98:


Оно ж все равно передается через конструктор. Следовательно, ту самую таблицу строк, каждая из которых имеет префикс длины (например, байтовый) непосредственно перед собой, в режиме компиляции так не сделаешь. Только где-нибудь с C++17, присобачив constexpr, можно надеяться, что компилятор полностью выполнит конструкторы сам. Но и тогда сколько-нибудь естественным способом не положить рядом байт длины и саму строку. Хотя через задницу, скорее всего, получится.

BFE>Просто или нет, но ведёт к изменению синтаксиса.


Его и так уже давно меняют в сторону полной неочевидности.
Re[17]: Об эффективности виртуальных функций
От: B0FEE664  
Дата: 08.08.24 16:06
Оценка:
Здравствуйте, Евгений Музыченко, Вы писали:

П>>Отсутствие опыта решения сложных задач делает их такими

ЕМ>Какие задачи (на уровне МК или обычного компьютера) Вы согласны считать "достаточно сложными" для получения адекватного опыта в программировании? Какие факторы превращают "несложную" задачу в "сложную"? А на ваших STMках какие задачи решаются?

Встряну: сложные задачи — это такие, которые не могут быть решены силами одного человека.
И каждый день — без права на ошибку...
Re[18]: Об эффективности виртуальных функций
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 08.08.24 16:14
Оценка:
Здравствуйте, B0FEE664, Вы писали:

BFE>сложные задачи — это такие, которые не могут быть решены силами одного человека.


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

Я бы в первую очередь назвал сложными задачи, для которых нет сколько-нибудь готовых алгоритмов решения. То есть, где нельзя просто найти алгоритм и выполнить его поэтапно, не привлекая изобретательности и творческого мышления вообще, или привлекая по минимуму.
Re[7]: Об эффективности виртуальных функций
От: B0FEE664  
Дата: 08.08.24 16:31
Оценка:
Здравствуйте, Евгений Музыченко, Вы писали:

ЕМ>Меня прям умиляет, как народ начал совершенно автоматически мыслить 64-разрядными архитектурами по умолчанию. Задачи, укладывающиеся в 32-разрядные, уже кончились?


А меня не удивляет, что народ не помнит, что размер указателя не обязан быть фиксированным. Стандарт не запрещает иметь указатель размером в один байт на элемент массива размером до 256 элементов.
И каждый день — без права на ошибку...
Re[8]: Об эффективности виртуальных функций
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 08.08.24 16:37
Оценка:
Здравствуйте, B0FEE664, Вы писали:

BFE>Стандарт не запрещает иметь указатель размером в один байт на элемент массива размером до 256 элементов.


Стандарт где-то предполагает возможность использования указателей, привязанных к конкретным объектам? По-моему, там имеются в виду модели памяти вроде сегментных, с переключаемыми банками и т.п.
Re[12]: Об эффективности виртуальных функций
От: andyp  
Дата: 08.08.24 17:27
Оценка:
Здравствуйте, karbofos42, Вы писали:

K>Ну, вот мне нужно определить наличие элемента в коллекции. Контейнер знает как он данные хранит и имеет представление как лучше до них добраться. Если у нас виртуальный метод contains во всех коллекциях, то вектор реализует его через перебор, а множество быстро посчитает хэш и полезет в дерево/таблицу. Если у нас только итераторы, то и в множестве медленно перебором будем бегать, не используя преимуществ структуры данных. По факту имеем необходимость знать внутреннее устройство и писать под конкретный тип коллекции, так что никакой абстракцией тут не пахнет, всё торчит наружу.


Во-первых, в stl std::set — это дерево. Структура, на основе хэш-таблицы — std::unordered_set.

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

Т.е. если твоя структура данных умеет в быстрый find или lower_bound, то он у этой структуры есть (см ассоциативные контейнеры в stl — тут для поиска по ключу используется древовидная структура контейнера), если нет — то используешь обобщенный алгоритм — есть целое семейство алгоритмов std::find*, делающее медленный линейный поиск. Если знаешь, что данные в последовательности сортированные, то есть std::binary_search, std::lower_bound и иже с ними. Все это барахло эффективно для любой последовательности настолько, насколько это возможно, так как может быть параметризовано по категориям итераторов (Например, все-таки для поиска в std::set лучше юзать методы контейнера — обобщенному алгоритму требуются расстояния между итераторами, что в случае итераторов в std::set ломает логарифмическую сложность поиска)

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

K>Значит и коллекции из STL плохие. Тот же вектор даёт доступ к элементам по индексу, а должен был делегировать эти тайные знания итераторам.


В векторе доступ по индексам оставили для тех, у кого еще тогда от итераторов бомбило Там еще доступ с проверкой диапазона индекса есть, кидающий исключения. Это вообще кто использует, но оставили.
Отредактировано 08.08.2024 17:29 andyp . Предыдущая версия .
Re[19]: Об эффективности виртуальных функций
От: B0FEE664  
Дата: 08.08.24 17:30
Оценка:
Здравствуйте, Евгений Музыченко, Вы писали:

BFE>>сложные задачи — это такие, которые не могут быть решены силами одного человека.

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

Нет, не любую. Размер Windows 55'000'000 строк исходного кода, а за всё свою карьеру программист пишет где-то 700'000 строк. Но пусть мы имеем дело с мощным программистом, который пишет на порядок больше. Получается 7 миллионов. Что-ж, такому программисту потребуется всего 7-8 жизней...

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


Алгоритмов? Серьёзно? Да на любую формально поставленную задачу опытный программист вам за 5 минут набрасает схему алгоритма. Да, скорее всего такой алгоритм потребует неимоверного количества ресурсов и не будет оптимальным, но работать будет.
И каждый день — без права на ошибку...
Re[9]: Об эффективности виртуальных функций
От: B0FEE664  
Дата: 08.08.24 17:36
Оценка:
Здравствуйте, Евгений Музыченко, Вы писали:

BFE>>Стандарт не запрещает иметь указатель размером в один байт на элемент массива размером до 256 элементов.

ЕМ>Стандарт где-то предполагает возможность использования указателей, привязанных к конкретным объектам?
Указатель всегда, либо нулевой, либо на функцию, либо привязан к объекту. Остальное UB.

ЕМ> По-моему, там имеются в виду модели памяти вроде сегментных, с переключаемыми банками и т.п.

Чего?
Указатель (не всякий) может быть преобразован к void*, но, насколько я помню, нигде не сказано, что sizeof любого указателя должен быть равен sizeof(void*).
И каждый день — без права на ошибку...
Re[20]: Об эффективности виртуальных функций
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 08.08.24 17:49
Оценка:
Здравствуйте, B0FEE664, Вы писали:

BFE>Размер Windows 55'000'000 строк исходного кода, а за всё свою карьеру программист пишет где-то 700'000 строк.


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

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


О том и речь — если потребных ресурсов ему не дадут, то придется искать алгоритм для имеющихся. А если готового нет, то придется изобретать. Вот тут и возникнет сложность.
Re[10]: Об эффективности виртуальных функций
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 08.08.24 17:54
Оценка:
Здравствуйте, B0FEE664, Вы писали:

BFE>Указатель (не всякий) может быть преобразован к void*, но, насколько я помню, нигде не сказано, что sizeof любого указателя должен быть равен sizeof(void*).


Это имеет смысл обсуждать, если известна хоть одна реализация, в которой объект содержит не полноценный адрес vtbl, а индекс в таблице их адресов. Я о таких реализациях не слышал, а Вы?
Re[12]: Об эффективности виртуальных функций
От: B0FEE664  
Дата: 08.08.24 18:04
Оценка:
Здравствуйте, karbofos42, Вы писали:

TB>>Во-первых, мегауниверсальный метод нужен редко, и тогда принимают пару итераторов.

K>Никогда не бывает такого, что ошиблись с выбором контейнера или объём/характер данных несколько изменился, что требуется вектор заменить на хэш-таблицу с быстрым поиском?
Ни разу такого не было. Более того, мне даже ни разу хэш-таблица не понадобилась.

K>Сидеть менять везде std::vector на std::unordered_set, а в итоге окажется, что вроде по скорости нормально выходит, но по памяти фигня, стоит попробовать что-то ещё. И опять сидеть всякие хелперы править, которым по сути плевать на тип коллекции?

K>Вопрос не в написании кода, а в его поддержке и развитии.
Не, это вопрос архитектуры.

TB>>Во-вторых, в реальном методе реального проекта ты знаешь с каким классом работаешь.


K>В реальном методе реального проекта я работаю с тем, что дали.

K>Если мне нужно найти элемент в коллекции и эта коллекция — вектор, то придётся искать перебором.
Зачем? Почему нельзя построить индекс?

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

Будите. Знаю я таки, пришедших из C#.

K>В C# я буду использовать виртуальный метод коллекции Contains, который скажет есть ли нужный объект в коллекции.

И который будет работать очень медленно.
И каждый день — без права на ошибку...
Re[21]: Об эффективности виртуальных функций
От: B0FEE664  
Дата: 08.08.24 18:11
Оценка:
Здравствуйте, Евгений Музыченко, Вы писали:

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


Ну так это сложность оптимизации, а не алгоритма. Оптимизации всегда сложны, а преждевременная оптимизация — корень всех зол. Поэтому, если кто-то говорит про медленность виртуальных функций, то давите его авторитетом Кнута.
И каждый день — без права на ошибку...
Re[11]: Об эффективности виртуальных функций
От: B0FEE664  
Дата: 08.08.24 18:29
Оценка:
Здравствуйте, Евгений Музыченко, Вы писали:

BFE>>Указатель (не всякий) может быть преобразован к void*, но, насколько я помню, нигде не сказано, что sizeof любого указателя должен быть равен sizeof(void*).

ЕМ>Это имеет смысл обсуждать, если известна хоть одна реализация, в которой объект содержит не полноценный адрес vtbl, а индекс в таблице их адресов. Я о таких реализациях не слышал, а Вы?

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

Мне это напоминает проблемы телефонистов, которые никак не могли понять устройство интернета: вот провод, вот по нему идёт сигнал... Какие пакеты? Какие ip-адреса? вы о чём?
А ведь именно абстрагирование от сигнала и "чудовищные" накладные расходы в передаваемых данных привели к созданию глобальной работающей сети.
И каждый день — без права на ошибку...
Re[13]: Об эффективности виртуальных функций
От: karbofos42 Россия  
Дата: 08.08.24 18:31
Оценка:
Здравствуйте, andyp, Вы писали:

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


Ну, ведь есть тот же istream. Фактически там может и быстро из памяти данные вытягивать, а может медленно по сети забирать или из файла.
Как-то с этим живут. Да и вообще абстракция — это вроде одна из заявленных ООП.

A>Ибо логарифм и линейная сложность — это жесть какое отличие на больших наборах данных.


Всё относительно.
Если относительно много относительно маленьких коллекций, то вполне можно обойтись перебором, чтобы не тратить память на всякие деревья с более быстрым поиском.
Re[13]: Об эффективности виртуальных функций
От: karbofos42 Россия  
Дата: 08.08.24 18:43
Оценка:
Здравствуйте, B0FEE664, Вы писали:

BFE>Зачем? Почему нельзя построить индекс?


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

BFE>Будите. Знаю я таки, пришедших из C#.


Так себе повод для гордости. На каждый чих половину программы переписывать.

BFE>И который будет работать очень медленно.


Будет работать медленнее ровно на разницу запуска виртуального метода и обычного.
Чтобы было очень медленно — это нужно не разово искать по большой коллекции, а очень много и часто искать по большой коллекции.
Re[22]: Об эффективности виртуальных функций
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 08.08.24 19:23
Оценка:
Здравствуйте, B0FEE664, Вы писали:

BFE>это сложность оптимизации, а не алгоритма.


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

BFE>преждевременная оптимизация — корень всех зол.


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

Я тут уже приводил пример с МК: можно исходить из того, чтобы взять среднего программиста, способного написать программу для мощного МК за $1, а можно из того, чтобы взять продвинутого, способного написать то же самое для МК за $0.1. Если предполагается выпустить миллион изделий, то разница составит $900k. Если отказаться от "преждевременной" оптимизации, и сразу заложиться на $1M, то в какой момент пора начинать оптимизацию, чтобы сэкономить $900k?
Re[12]: Об эффективности виртуальных функций
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 08.08.24 19:25
Оценка:
Здравствуйте, B0FEE664, Вы писали:

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


А если абстрагироваться до машины Тьюринга, это поможет программистам понимать, как оно устроено и работает?
Re[6]: Об эффективности виртуальных функций
От: Pauel Беларусь http://blogs.rsdn.org/ikemefula
Дата: 08.08.24 19:43
Оценка:
Здравствуйте, Евгений Музыченко, Вы писали:

P>>Сотни тысяч это всё равно не тот масштаб


ЕМ>Исходя из чего?


Современный процессор выполняет миллиарды таких операций в секунду.
Подозреваю, узким местом будет все равно память или шина, но тем не менее.
Re[13]: Об эффективности виртуальных функций
От: B0FEE664  
Дата: 08.08.24 22:39
Оценка:
Здравствуйте, Евгений Музыченко, Вы писали:

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

ЕМ>А если абстрагироваться до машины Тьюринга, это поможет программистам понимать, как оно устроено и работает?

Понимание принципа работы машины Тьюринга позволяет программировать на чём угодно дискретном: на лампах, на транзисторах, на трисолярианах. При этом вовсе не обязательно знать, как оно там устроено и работает.
И каждый день — без права на ошибку...
Re[20]: Об эффективности виртуальных функций
От: пффф  
Дата: 08.08.24 22:45
Оценка: :)
Здравствуйте, B0FEE664, Вы писали:

BFE>Нет, не любую. Размер Windows 55'000'000 строк исходного кода, а за всё свою карьеру программист пишет где-то 700'000 строк. Но пусть мы имеем дело с мощным программистом, который пишет на порядок больше.


Что-то про 700К за жизнь сомнительно. За год — более похоже
Re[23]: Об эффективности виртуальных функций
От: B0FEE664  
Дата: 08.08.24 23:04
Оценка:
Здравствуйте, Евгений Музыченко, Вы писали:

BFE>>это сложность оптимизации, а не алгоритма.

ЕМ>Оптимизация нередко приводит к изменению алгоритма.
Было бы странное, если бы это было не так.

BFE>>преждевременная оптимизация — корень всех зол.

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

ЕМ>Я тут уже приводил пример с МК: можно исходить из того, чтобы взять среднего программиста, способного написать программу для мощного МК за $1, а можно из того, чтобы взять продвинутого, способного написать то же самое для МК за $0.1. Если предполагается выпустить миллион изделий, то разница составит $900k. Если отказаться от "преждевременной" оптимизации, и сразу заложиться на $1M, то в какой момент пора начинать оптимизацию, чтобы сэкономить $900k?

Это зависит от цены конечного изделия. Если это автомобиль за 100'000$, то этим вообще не стоит заниматься. Если же это брелок за 2 евро, то после продажи первых 100'000, но и то — не факт, зависит от функционала. Может оказаться, что гибкость и вариативность важнее для продаж, чем цена.
И каждый день — без права на ошибку...
Re[21]: Об эффективности виртуальных функций
От: B0FEE664  
Дата: 08.08.24 23:22
Оценка:
Здравствуйте, пффф, Вы писали:

BFE>>Нет, не любую. Размер Windows 55'000'000 строк исходного кода, а за всё свою карьеру программист пишет где-то 700'000 строк. Но пусть мы имеем дело с мощным программистом, который пишет на порядок больше.

П>Что-то про 700К за жизнь сомнительно. За год — более похоже
А вы поинтересуйтесь статистикой. Сколько у Microsoft сейчас программистов? тысяч сто, наверное?
Если бы программисты Microsoft работали с такой интенсивностью, как вы пишите, то за год они смогли бы выпустить 1000 операционных систем написанных с нуля. 3 новых операционных системы каждый день!
И каждый день — без права на ошибку...
Re[14]: Об эффективности виртуальных функций
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 09.08.24 08:01
Оценка: +1
Здравствуйте, B0FEE664, Вы писали:

BFE>Понимание принципа работы машины Тьюринга позволяет программировать на чём угодно дискретном: на лампах, на транзисторах, на трисолярианах.


Да, как и понимание основ философии позволяет видеть закономерности и генерировать идеи. Но на практике это применяется плохо. Сколько Вам лично известно программистов, применяющих знание принципа работы машины Тьюринга в своей работе, чем конкретно они занимаются, и как незнание этого принципа повлияло бы на их результаты?
Re[22]: Об эффективности виртуальных функций
От: пффф  
Дата: 09.08.24 09:47
Оценка:
Здравствуйте, B0FEE664, Вы писали:

BFE>>>Нет, не любую. Размер Windows 55'000'000 строк исходного кода, а за всё свою карьеру программист пишет где-то 700'000 строк. Но пусть мы имеем дело с мощным программистом, который пишет на порядок больше.

П>>Что-то про 700К за жизнь сомнительно. За год — более похоже
BFE> А вы поинтересуйтесь статистикой. Сколько у Microsoft сейчас программистов? тысяч сто, наверное?
BFE>Если бы программисты Microsoft работали с такой интенсивностью, как вы пишите, то за год они смогли бы выпустить 1000 операционных систем написанных с нуля. 3 новых операционных системы каждый день!

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

А один перец написал qemu
Re[6]: Об эффективности виртуальных функций
От: Sinclair Россия https://github.com/evilguest/
Дата: 10.08.24 06:45
Оценка: +2
Здравствуйте, пффф, Вы писали:

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

Не верю я, что хоть когда-то такое было. Первый Excel вышел ещё до COM. И там до сих пор торчат уши 16-разрядной версии.
В ней, естественно, всё было утоптано так, что мама не горюй. Ограничения на количество столбцов и строк, починенные только в этом веке, как раз оттуда.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[7]: Об эффективности виртуальных функций
От: пффф  
Дата: 11.08.24 10:34
Оценка:
Здравствуйте, Sinclair, Вы писали:

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

S>Не верю я, что хоть когда-то такое было.

Твоя проблема. Я читал в какой-то книге про COM


S>Первый Excel вышел ещё до COM.


OLE вышел тоже до COM


S>И там до сих пор торчат уши 16-разрядной версии.

S>В ней, естественно, всё было утоптано так, что мама не горюй. Ограничения на количество столбцов и строк, починенные только в этом веке, как раз оттуда.

Видимо, с начала было не так утоптано
Re[8]: Об эффективности виртуальных функций
От: Sinclair Россия https://github.com/evilguest/
Дата: 12.08.24 05:20
Оценка: :)
Здравствуйте, пффф, Вы писали:
П>Твоя проблема. Я читал в какой-то книге про COM


S>>Первый Excel вышел ещё до COM.

П>OLE вышел тоже до COM
И?

S>>И там до сих пор торчат уши 16-разрядной версии.

S>>В ней, естественно, всё было утоптано так, что мама не горюй. Ограничения на количество столбцов и строк, починенные только в этом веке, как раз оттуда.

П>Видимо, с начала было не так утоптано

Ага. То есть сначала написали Excel под машинки с полумегабайтом памяти, используя отдельный ком-объект под каждую ячейку.
А уже потом, когда памяти стало побольше, его решили утоптать. </sarcasm>

Если спороли чушь, Дмитрий, имейте смелость признать это.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[9]: Об эффективности виртуальных функций
От: пффф  
Дата: 12.08.24 10:00
Оценка: :)
Здравствуйте, Sinclair, Вы писали:


П>>Видимо, с начала было не так утоптано

S>Ага. То есть сначала написали Excel под машинки с полумегабайтом памяти, используя отдельный ком-объект под каждую ячейку.

Возможно, и не написали, а сразу дотумкали. Или написали, посмотрели, что получилось не айс, не выпустив в прод сели переписали

Интересной стороной систем второй волны является то, что реализация рассматривается как черный ящик. Это означает, что все детали реализации считаются непрозрачными (opaque) для клиентов объекта. Часто, когда разработчики начинают использовать такие основанные на интерфейсах технологии, как СОМ, то уровень свободы, которую дает эта непрозрачность, игнорируется, что побуждает неопытных разработчиков весьма упрощенно рассматривать отношения между интерфейсом, реализацией и объектом. Рассмотрим электронную таблицу Excel, которая выставляет свои функциональные возможности, используя СОМ. Реализация класса электронной таблицы Excel выставляет около 25 различных интерфейсов СОМ, что позволяет ей применять множество основанных на СОМ технологий (Linking, Embedding, Inplace Activation, Automation, Active Document Objects, Hyperlinking и т. д.). Поскольку каждому интерфейсу требуется по четырехбайтному указателю виртуальной функции (vptr) на объект, объекты электронной таблицы заполняют около 100 байт служебными данными, в добавление к любому конкретному состоянию электронной таблицы, которое может потребоваться для хранения пользовательских данных. Поскольку данный объект электронной таблицы может состоять из весьма большого количества ячеек, эти 100 байт служебных данных погашаются сотнями килобайт, которые может потребовать большая таблица для управления содержимым каждой используемой ячейки.

Фактическая реализация электронной таблицы Excel осложняется тем, что к каждой отдельной ячейке электронной таблицы можно обращаться также через интерфейсы СОМ. С точки зрения СОМ каждый из интерфейсов ячейки представляет собой определенную идентификационную единицу СОМ и не может быть обнаружен с помощью опросов объекта электронной таблицы функцией QueryInterface. Вместо этого интерфейсы ячеек обнаруживаются путем использования одного из альтернативных интерфейсов (например, IOleItemContainer), которые объект электронной таблицы выставляет для своих клиентов. Тот факт, что теперь каждая ячейка раскрывается для клиентов через интерфейсы СОМ, означает, что разработчик Excel должен позаботиться о недопущении чрезмерного количества служебных данных, относящихся к СОМ. Рассмотрим объект электронной таблицы, состоящей из 1000 ячеек. Предположим для простоты вычислений, что каждой ячейке требуется в среднем по 16 байт памяти для хранения исходного состояния ячейки Excel. Это означает, что таблица из 1000 элементов потребляет примерно 16 000 байт памяти, не связанной с СОМ. Для этой таблицы 100 байт служебных записей указателя виртуальной функции, помещенных интерфейсами табличного уровня, оказывают очень малое влияние на потребление памяти. Однако поскольку каждая отдельная ячейка может самостоятельно выставлять примерно восемь отдельных интерфейсов СОМ, то для каждой ячейки 32 байта могут быть заняты для служебных записей, касающихся управления указателями виртуальных функций ячейки. При использовании простых технологий реализации, которые включены в большинство сред разработки СОМ, 1000-ячеечной электронной таблице понадобится примерно 32 100 байт памяти для указателей виртуальных функций, что примерно вдвое превышает объем памяти, занимаемой исходными данными Excel. Ясно, что такие служебные записи чрезмерны.

Для того чтобы понять, как команда разработчиков Excel решила данную проблему расхода памяти на указатели vptr , полезно вновь проверить отношения между состоянием и поведением, как оно обычно реализовано в СОМ. На рис. A.1 показан простейший объект СОМ в памяти. Отметим, что блок памяти, занимаемый объектом, состоит из указателей vptr и элементов данных. Можно рассматривать этот рисунок, считая, что элементы данных представляют состояние объекта, а указатели виртуальных функций – его поведение. В большинстве реализаций объектов эти два аспекта объекта записаны в непрерывном блоке памяти. Однако СОМ не настаивает на этом. СОМ просто имеет дело с указателями vptr , а управление состоянием предоставляет разработчику. СОМ вполне счастлив, если разработчик решит разместить состояние объекта и vptr в различных блоках памяти, как показано на рис. А.2. В конце концов, то, как происходит управление состоянием объекта, является всего лишь одной из деталей реализации, скрытой от клиента за стеной интерфейсов объекта.

Так как СОМ не требует, чтобы состояние объекта было размещено рядом с его указателями vptr, команда разработчиков Excel смогла значительно уменьшить потребление памяти. Рассмотрим отдельную ячейку электронной таблицы. Хотя для записи содержимого ячейки необходимо выделить 16 байт памяти, но 32 байта памяти, необходимых для vptr ячейки, не обязательно размещать в едином блоке памяти вместе с данными ячейки. Кроме того, если к ячейке не осуществляется доступ через ее СОМ-интерфейсы, то эти 32 байта памяти для vptr вообще не нужны. Это означает, что Excel может просто динамически размещать блоки памяти для vptr, по принципу «ячейка к ячейке» (cell-by-cell). Поскольку к большей части ячеек обращения через интерфейсы СОМ не будет никогда, это означает, что фактически в большинстве случаев не будет и затрат на vptr. Этот принцип создания «невесомых» объектов (flyweight objects), предназначенных для обеспечения поведения по необходимости, является вариантом «отделяемой» (tearoff) технологии, которая была впервые предложена в великолепной книге Криспина Госвелла «Сборник рецептов программиста СОМ» (Crispin Goswell. СОМ Programmer's Cookbook) ( http://www.microsoft.com/oledev). Обе эти технологии используют отложенное вычисление (lazy evaluation) для задержки выделения памяти указателям vptr.


https://coollib.in/b/54426-donald-boks-suschnost-tehnologii-som-biblioteka-programmista/read


S>А уже потом, когда памяти стало побольше, его решили утоптать. </sarcasm>


S>Если спороли чушь,


Право пороть чушь оставляю вам


S>Дмитрий, имейте смелость признать это.


Дмитрий? Хм. Кем меня тут только не называли
Re[3]: Об эффективности виртуальных функций
От: Sergey_BG Россия  
Дата: 13.08.24 12:04
Оценка:
ЕМ>Если задаться целью написать подходящий пример, то я могу сделать разницу и на два порядка. Речь-то не о крайних показательных примерах, а об общем случае.
Я не понял, что вы имели в виду. Поясните пожалуйста.
1) В общем случае, как я понимаю, финал ничего не даст, так как обычно используют интерфейсы, и оптимизация final не сработает.
2) Я показывал различие вызова статического метода и виртуального. А что в общем случае? Статические будут вызывать дольше из за раздутия кода инлайнами?
Сергей
Re[10]: Об эффективности виртуальных функций
От: Sinclair Россия https://github.com/evilguest/
Дата: 13.08.24 13:19
Оценка:
Здравствуйте, пффф, Вы писали:

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



П>>>Видимо, с начала было не так утоптано

S>>Ага. То есть сначала написали Excel под машинки с полумегабайтом памяти, используя отдельный ком-объект под каждую ячейку.

П>Возможно, и не написали, а сразу дотумкали. Или написали, посмотрели, что получилось не айс, не выпустив в прод сели переписали

Вы сейчас претендуете забрать пальму первенства в дисциплине "я придумываю фантастические объяснения обычным явлениям" у vdimas.
Зачем?

П>https://coollib.in/b/54426-donald-boks-suschnost-tehnologii-som-biblioteka-programmista/read

О, спасибо, крайне интересный текст.
И тем не менее — первый Excel вышел под платформу, где не было ни COM, ни OLE. Поэтому очень вряд ли бы там был написан код, который под каждую ячейку книги конструирует COM-объект или его подобие.
COM прикручивали к уже существующему движку.
И в тексте, который вы процитировали, написано, каким способом это было сделано. Вместе с объяснением причин, по которым любая другая реализация была бы безумием.
Не нужно считать программистов прошлого идиотами.

П>Право пороть чушь оставляю вам

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

П>Дмитрий? Хм. Кем меня тут только не называли

Простите, перепутал аккаунты.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[4]: Об эффективности виртуальных функций
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 13.08.24 20:11
Оценка:
Здравствуйте, Sergey_BG, Вы писали:

S_B>1) В общем случае, как я понимаю, финал ничего не даст, так как обычно используют интерфейсы, и оптимизация final не сработает.


Общий случай — это когда функция делает достаточно полезной работы, чтобы стоимость вызова не слишком выделялась на фоне общего времени от вызова до возврата. В таких случаях какой в среднем получается разница между использованием обычной и виртуальной функции?
Re[10]: Об эффективности виртуальных функций
От: T4r4sB Россия  
Дата: 13.08.24 22:01
Оценка:
Здравствуйте, пффф, Вы писали:

П>Так как СОМ не требует, чтобы состояние объекта было размещено рядом с его указателями vptr, команда разработчиков Excel смогла значительно уменьшить потребление памяти. Рассмотрим отдельную ячейку электронной таблицы. Хотя для записи содержимого ячейки необходимо выделить 16 байт памяти, но 32 байта памяти, необходимых для vptr ячейки, не обязательно размещать в едином блоке памяти вместе с данными ячейки. Кроме того, если к ячейке не осуществляется доступ через ее СОМ-интерфейсы, то эти 32 байта памяти для vptr вообще не нужны.


А, в Русте ООП так сделано. Классы не хранят никаких указателей на таблицы.
А если нужен полиморфизьм — то передавай указатель на интерфейс, который на самом деле является fat pointer и состоит из пары "указатель на таблицу методов" и "указатель на саму структуру".
Это позволяет для любого класса реализовать хоть сто интерфейсов без ущерба для размера этого класса.
Нет такой подлости и мерзости, на которую бы не пошёл gcc ради бессмысленных 5% скорости в никому не нужном синтетическом тесте
Re[15]: Об эффективности виртуальных функций
От: B0FEE664  
Дата: 13.08.24 23:36
Оценка: :)
Здравствуйте, Евгений Музыченко, Вы писали:

BFE>>Понимание принципа работы машины Тьюринга позволяет программировать на чём угодно дискретном: на лампах, на транзисторах, на трисолярианах.

ЕМ>Да, как и понимание основ философии позволяет видеть закономерности и генерировать идеи. Но на практике это применяется плохо. Сколько Вам лично известно программистов, применяющих знание принципа работы машины Тьюринга в своей работе, чем конкретно они занимаются, и как незнание этого принципа повлияло бы на их результаты?

Я не знаю ни одного программиста, который бы не использовал те же принципы программирования, что используются для программирования машины Тьюринга. Я только слышал и читал о таких, которые программируют на аналоговых компьютерах.
И каждый день — без права на ошибку...
Re[16]: Об эффективности виртуальных функций
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 14.08.24 14:21
Оценка:
Здравствуйте, B0FEE664, Вы писали:

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


А я не знаю ни одного светодиодного фонарика, в работе которого не использовались бы принципы квантовой механики. Когда Вы включаете светодиодный фонарик, какие именно познания в квантовой механике помогают Вам это делать?
Re[17]: Об эффективности виртуальных функций
От: B0FEE664  
Дата: 16.08.24 01:10
Оценка: :)
Здравствуйте, Евгений Музыченко, Вы писали:

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


ЕМ>А я не знаю ни одного светодиодного фонарика, в работе которого не использовались бы принципы квантовой механики. Когда Вы включаете светодиодный фонарик, какие именно познания в квантовой механике помогают Вам это делать?


Вы меня спрашиваете как физика, как инженера, или как пользователя фонарика?
Это я к тому, что ваша кривая аналогия не подходит к вопросу: как пользователь программы не обязан знать о машине Тьринга, так и пользователь фонарика не обязан знать, про p-n переход и энергетические уровни электронов в атоме.
И каждый день — без права на ошибку...
Re[9]: Об эффективности виртуальных функций
От: landerhigh Пират  
Дата: 16.08.24 09:04
Оценка:
Здравствуйте, Евгений Музыченко, Вы писали:

ЕМ>А бОльшая часть софта для промышленных, реально массовых, 8- и 16-разрядных МК, таки написана на C.


Промышленный софт уже 30 лет пишется либо на плюсах, либо на кошмарной "эмуляции плюсов вручную".

ЕМ>Для большинства моделей попросту нет плюсовых компиляторов,


По нынешним временам те полтора хромых МК, для которых нет gcc — это давно далеко не "большинство".
www.blinnov.com
Re[18]: Об эффективности виртуальных функций
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 16.08.24 09:08
Оценка:
Здравствуйте, B0FEE664, Вы писали:

BFE>ваша кривая аналогия не подходит к вопросу: как пользователь программы не обязан знать о машине Тьринга, так и пользователь фонарика не обязан знать, про p-n переход и энергетические уровни электронов в атоме.


Моя кривая аналогия о том, что я имею лишь общее теоретическое представление о машине Тьюринга, и никогда не вспоминаю о ней в процессе программирования.

Было бы крайне интересно узнать, каким образом совершенствование познаний о машине Тьюринга могло бы помочь мне совершенствоваться в умении программировать.
Re[10]: Об эффективности виртуальных функций
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 16.08.24 09:15
Оценка:
Здравствуйте, landerhigh, Вы писали:

L>Промышленный софт уже 30 лет пишется либо на плюсах, либо на кошмарной "эмуляции плюсов вручную".


Вы, похоже, говорите о софте для "серьезных компьютеров", а я говорил о софте для мелких МК.

ЕМ>>Для большинства моделей попросту нет плюсовых компиляторов,


L>По нынешним временам те полтора хромых МК, для которых нет gcc — это давно далеко не "большинство".


Ну вот тот же реально массовый Holtek — ни слова о C++.
Re[11]: Об эффективности виртуальных функций
От: landerhigh Пират  
Дата: 16.08.24 10:21
Оценка:
Здравствуйте, Евгений Музыченко, Вы писали:

L>>Промышленный софт уже 30 лет пишется либо на плюсах, либо на кошмарной "эмуляции плюсов вручную".

ЕМ>Вы, похоже, говорите о софте для "серьезных компьютеров", а я говорил о софте для мелких МК.

Я знаю, о чем говорю.

ЕМ>>>Для большинства моделей попросту нет плюсовых компиляторов,

L>>По нынешним временам те полтора хромых МК, для которых нет gcc — это давно далеко не "большинство".
ЕМ>Ну вот тот же реально массовый Holtek — ни слова о C++.

Реально массовый?
www.blinnov.com
Re[12]: Об эффективности виртуальных функций
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 16.08.24 16:13
Оценка:
Здравствуйте, landerhigh, Вы писали:

L>Реально массовый?


Да, реально. Он стоит почти в каждом мелком гаджете, где нужно что-то измерять, контролировать и отображать, но не требуется особого интеллекта, быстродействия или памяти — в зарядниках, преобразователях питания, энергометрах, контроллерах нагрузки, индикаторах CO/CO2/HVOC и подобном.
Re: Об эффективности виртуальных функций
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 17.08.24 10:31
Оценка: +2
Здравствуйте, Евгений Музыченко, Вы писали:

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


Тут можно сравнивать инлайнинг с вызовом метода.
Суть сколько времени уходит на работу со стеком относительно инлайнового вызова.
Если вызов типа int+int или int<int в тех же сортировках то конечно доля огромная. Но в большинстве своем методы намного более длительные чем затраты на VMT и стек.

Проблема больше в скорости программирования и отладки.
и солнце б утром не вставало, когда бы не было меня
Re[19]: Об эффективности виртуальных функций
От: B0FEE664  
Дата: 19.08.24 10:14
Оценка:
Здравствуйте, Евгений Музыченко, Вы писали:

ЕМ>Моя кривая аналогия о том, что я имею лишь общее теоретическое представление о машине Тьюринга, и никогда не вспоминаю о ней в процессе программирования.

Большинство людей используют такие свойства чисел как транзитивность и коммутативность не задумываясь об этом.

ЕМ>Было бы крайне интересно узнать, каким образом совершенствование познаний о машине Тьюринга могло бы помочь мне совершенствоваться в умении программировать.

Поясняю.
Ваша постановка вопроса говорит о склонности вашего ума программировать исходя из архитектуры машины, а надо наоборот: думать и программировать вне рамок архитектуры машины, а результат адаптировать к архитектуре машины. Второй подход потенциально приводит к изобретению и созданию чего-то нового, а ваш подход ведёт просто к переписыванию одного и того же с разными вариациями.
И каждый день — без права на ошибку...
Re[20]: Об эффективности виртуальных функций
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 19.08.24 10:40
Оценка:
Здравствуйте, B0FEE664, Вы писали:

BFE>Ваша постановка вопроса говорит о склонности вашего ума программировать исходя из архитектуры машины


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

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

BFE>надо наоборот: думать и программировать вне рамок архитектуры машины, а результат адаптировать к архитектуре машины.


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

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


Вы, похоже, никогда не интересовались патентами на решения, применимые только к конкретным архитектурам.
Re[21]: Об эффективности виртуальных функций
От: so5team https://stiffstream.com
Дата: 19.08.24 11:02
Оценка:
Здравствуйте, Евгений Музыченко, Вы писали:

BFE>>надо наоборот: думать и программировать вне рамок архитектуры машины, а результат адаптировать к архитектуре машины.


ЕМ>Надо, если вероятность того, что продукт программирования будет использоваться на разных архитектурах, сколько-нибудь значима. Если такая перспектива не просматривается, то не надо.


Ну вот вы, Евгений, тридцать лет надрачивались писать драйвера Windows под x86/64. Как вы оценивали вероятность необходимости написания драйверов Windows под ARM? Как вы оцениваете эту вероятность сейчас? Много ли в предметной области обработки звука так сильно завязано на x86/64, что это нужно полностью переписать под ARM?
Re[21]: Об эффективности виртуальных функций
От: B0FEE664  
Дата: 19.08.24 12:52
Оценка:
Здравствуйте, Евгений Музыченко, Вы писали:

BFE>>Ваша постановка вопроса говорит о склонности вашего ума программировать исходя из архитектуры машины

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

Так имеет смысл писать только тесты проверки софта или железа. Про всё остальное невозможно знать заведомо, что понадобится в будущем.

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

Опять аналогии? А чего ж на шурупы-то? Если встроить прямо в стену, то и надёжней и снести можно будет только вместе со стеной.

BFE>>надо наоборот: думать и программировать вне рамок архитектуры машины, а результат адаптировать к архитектуре машины.

ЕМ>Надо, если вероятность того, что продукт программирования будет использоваться на разных архитектурах, сколько-нибудь значима. Если такая перспектива не просматривается, то не надо.
Каковы вероятность, что DOOM запустят на электронном тесте на беременность? Ответ:1.
Итак, как вы подсчитываете такую вероятность?

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

ЕМ>Вы, похоже, никогда не интересовались патентами на решения, применимые только к конкретным архитектурам.
Обычно патенты пишут как можно более общими, чтобы иметь возможность продавать права на платформы, под которые сами патент не используют. В детали таких договоров не вникал, не было повода.
И каждый день — без права на ошибку...
Re[22]: Об эффективности виртуальных функций
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 19.08.24 16:08
Оценка:
Здравствуйте, so5team, Вы писали:

S>тридцать лет надрачивались писать драйвера Windows под x86/64.


Справедливости ради, сперва я лет пятнадцать надрачивался писать под x86, и лишь потом добавил к этому x64. Как и все, собственно.

S>Как вы оценивали вероятность необходимости написания драйверов Windows под ARM?


Боюсь испортить Вам драматизм момента, но первый драйвер для Windows под ARM, как и некоторый другой софт, я писал еще лет десять назад, под Windows CE.

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

S>Как вы оцениваете эту вероятность сейчас?


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

S>Много ли в предметной области обработки звука так сильно завязано на x86/64, что это нужно полностью переписать под ARM?


У меня — почти ничего, поэтому основной геморрой при добавлении платформы ARM64 был с адаптацией под новые компилятор/линкер и библиотеки. Как только оно стало собираться ими под x86/x64, так автоматом собралось и под ARM64.

Но я не использую сложную обработку звука — у меня в основном софт для организации системных интерфейсов и управления ими. А те, кто делает обработку, синтез, распознавание, плотно используют SSE и подобные расширения. Им свои алгоритмы приходится неслабо переписывать, поэтому многие до сих пор не выпустили версий под ARM.
Re[22]: Об эффективности виртуальных функций
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 19.08.24 16:29
Оценка:
Здравствуйте, B0FEE664, Вы писали:

BFE>Про всё остальное невозможно знать заведомо, что понадобится в будущем.


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

BFE>А чего ж на шурупы-то? Если встроить прямо в стену, то и надёжней и снести можно будет только вместе со стеной.


То есть, у Вас дома вся проводка на роликах, все трубы на зажимах, чтоб в любой момент можно было переложить?

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

BFE>Каковы вероятность, что DOOM запустят на электронном тесте на беременность? Ответ:1.


В описанных условиях (процессор с объемом ОЗУ 64 байта) — строго нулевая. Мне лень разыскивать первоисточники, но или это не DOOM, а игрушка типа пресловутого волка с яйцами, или ресурсов в процессоре на несколько порядков больше, или это полностью фейк.

BFE>как вы подсчитываете такую вероятность?


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

BFE>Обычно патенты пишут как можно более общими


Если технология применяется в конкретных условиях (скажем, особенности кодогенерации для процессоров с определенным алгоритмом предсказания ветвлений), то попытка чрезмерно расширить описание патента приведет к снижению конкретики ниже допустимого порога, и заявку попросту забракуют.
Re: Об эффективности виртуальных функций
От: scf  
Дата: 19.08.24 20:29
Оценка:
Здравствуйте, Евгений Музыченко, Вы писали:

ЕМ>Что эти люди, которые переживали (а некоторые и сейчас переживают, судя по дискуссиям) о "стоимости вызова", собирались делать с помощью виртуальных функций? Если вызывать их сотни тысяч раз в секунду и чаще, то и при обычном прямом вызове такие функции будут сильно тормозить. А если вызывать с разумной частотой, то лишь в очень редких случаях можно обнаружить заметную разницу.


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

С другой стороны, в современном мире отличие может быть и несущественным. Процессоры научились в indirect branch prediction https://en.wikipedia.org/wiki/Branch_predictor#Indirect_branch_predictor , Java умееет рекомпилировать виртуальные вызовы в прямые по набранной статистике, gcc девиртуализует вызовы, если у него есть достаточно информации о типах.
Re[2]: Об эффективности виртуальных функций
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 19.08.24 21:04
Оценка:
Здравствуйте, scf, Вы писали:

scf>когда пишешь код, утилизирующий 100% цпу.


Или софт, который будет работать вместе с другим софтом, которому неплохо бы оставить достаточный резерв.
Re[23]: Об эффективности виртуальных функций
От: so5team https://stiffstream.com
Дата: 20.08.24 04:29
Оценка:
Здравствуйте, Евгений Музыченко, Вы писали:

S>>Как вы оценивали вероятность необходимости написания драйверов Windows под ARM?


ЕМ>Боюсь испортить Вам драматизм момента, но первый драйвер для Windows под ARM, как и некоторый другой софт, я писал еще лет десять назад, под Windows CE.


Прекрасно. В 2019-ом году, когда Windows CE перестала быть актуальной, вероятность вы как оценивали?

ЕМ>То, что может потребоваться расширить спектр поддерживаемых архитектур, я предполагал, но никак не закладывался на конкретные возможные варианты.


Боюсь, здесь тему можно и закрывать, т.к. вы сами подтверждаете тезис тов.B0FEE664 "думать и программировать вне рамок архитектуры машины, а результат адаптировать к архитектуре машины".

В том числе и потому что:

ЕМ>У меня — почти ничего, поэтому основной геморрой при добавлении платформы ARM64 был с адаптацией под новые компилятор/линкер и библиотеки. Как только оно стало собираться ими под x86/x64, так автоматом собралось и под ARM64.
Re[24]: Об эффективности виртуальных функций
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 20.08.24 07:51
Оценка:
Здравствуйте, so5team, Вы писали:

S>В 2019-ом году, когда Windows CE перестала быть актуальной, вероятность вы как оценивали?


Вероятность того, что потребуется еще какой-то софт для CE — как очень низкую. Вероятность того, что распространенность винды на ARM64 будет расти — как достаточно высокую.

S>вы сами подтверждаете тезис тов.B0FEE664 "думать и программировать вне рамок архитектуры машины, а результат адаптировать к архитектуре машины".


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

S>В том числе и потому что:


ЕМ>>У меня — почти ничего, поэтому основной геморрой при добавлении платформы ARM64 был с адаптацией под новые компилятор/линкер и библиотеки. Как только оно стало собираться ими под x86/x64, так автоматом собралось и под ARM64.


Это не моя заслуга, а MS. Они еще в 80-х, начиная делать NT для x86, Alpha и MIPS, заложили хороший (и разумный!) уровень абстракции и совместимости.
Re[23]: Об эффективности виртуальных функций
От: B0FEE664  
Дата: 22.08.24 16:06
Оценка:
Здравствуйте, Евгений Музыченко, Вы писали:

BFE>>Про всё остальное невозможно знать заведомо, что понадобится в будущем.

ЕМ>А и не надо. Достаточно лишь в общих чертах представлять, какие тенденции могут возникнуть в обозримом будущем.
Так "заведомо под архитектуру конкретной машины" или же "в общих чертах представлять, какие тенденции могут возникнуть в обозримом будущем"?

BFE>>А чего ж на шурупы-то? Если встроить прямо в стену, то и надёжней и снести можно будет только вместе со стеной.


ЕМ>То есть, у Вас дома вся проводка на роликах, все трубы на зажимах, чтоб в любой момент можно было переложить?

Не я делал проводку в доме, что купил.

ЕМ>Я, кстати, одобряю скрытую проводку, а вот замоноличенную в стену трубу одобряю только цельную пластиковую. Все по ситуации.

А я не одобряю аналогии. Причём тут проводка?

BFE>>Каковы вероятность, что DOOM запустят на электронном тесте на беременность? Ответ:1.

ЕМ>В описанных условиях (процессор с объемом ОЗУ 64 байта) — строго нулевая. Мне лень разыскивать первоисточники, но или это не DOOM, а игрушка типа пресловутого волка с яйцами, или ресурсов в процессоре на несколько порядков больше, или это полностью фейк.
Там по ссылке видеозапись есть.

BFE>>как вы подсчитываете такую вероятность?

ЕМ>Из примерной оценки сложности игры (хотя бы отдельного ее эпизода) и объема ресурсов, потребного для реализации такой сложности.
То есть произвольно и зависит исключительно от вас. Это не метод.

BFE>>Обычно патенты пишут как можно более общими

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

И какая польза от такого патента? Поди вред один...
И каждый день — без права на ошибку...
Re[24]: Об эффективности виртуальных функций
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 22.08.24 17:02
Оценка:
Здравствуйте, B0FEE664, Вы писали:

BFE>Так "заведомо под архитектуру конкретной машины" или же "в общих чертах представлять, какие тенденции могут возникнуть в обозримом будущем"?


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

BFE>Не я делал проводку в доме, что купил.


Если б делали, то непременно наружную, на роликах?

BFE>А я не одобряю аналогии.


И совершенно зря. Говорят, начиная с какого-то не слишком взрослого возраста, мышление работает в основном по аналогии с уже известным. Усваивать совершенно новые понятия и принципы, никак не связанные с известными, мозг практически не в состоянии.

BFE>Причём тут проводка?


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

BFE>Там по ссылке видеозапись есть.


Вам накидать ссылок на "видеозаписи" очевидно невозможных процессов? Вы никогда не слышали ни о иллюзионизме, ни о видеомонтаже? Если я завтра выложу видеозапись, как я в редакторе FAR'а, с нуля, по памяти, наколачиваю на ассемблере полный аналог линуксового ядра, Вы согласитесь признать меня великим програмистом?

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

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


BFE>То есть произвольно и зависит исключительно от вас. Это не метод.


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

BFE>И какая польза от такого патента? Поди вред один...


Я правильно понимаю, что все Ваши познания о патентной системе почерпнуты из срачей о патентных троллях?
Re[25]: Об эффективности виртуальных функций
От: B0FEE664  
Дата: 22.08.24 17:27
Оценка:
Здравствуйте, Евгений Музыченко, Вы писали:

BFE>>Так "заведомо под архитектуру конкретной машины" или же "в общих чертах представлять, какие тенденции могут возникнуть в обозримом будущем"?

ЕМ>Конкретная машина — это типовая современная машина с процессором, памятью с произвольным доступом, регистрами, потоком выполнения команд и прочими атрибутами, под которые изначально затачивался язык C. Для программирования такой машины на любом доступном языке не требуется совершенно никаких познаний о машинах Тьюринга.
Действительно, ведь различия столь существенны!

BFE>>Не я делал проводку в доме, что купил.

ЕМ>Если б делали, то непременно наружную, на роликах?
Уж я бы точно не экономил на длине кабеля.

BFE>>А я не одобряю аналогии.

ЕМ>И совершенно зря. Говорят, начиная с какого-то не слишком взрослого возраста, мышление работает в основном по аналогии с уже известным. Усваивать совершенно новые понятия и принципы, никак не связанные с известными, мозг практически не в состоянии.
Это верно для большинства, но не для всех.

BFE>>Причём тут проводка?

ЕМ>При том, что по открытой проводке сразу можно более-менее уверено сказать, на какой она ток, когда примерно делалась, откуда и куда идет, и т.п. То есть, это конкретика. Скрытой проводки не видно, видны лишь пользовательские конечные точки (розетки) — это абстракция.
Конечно-конечно. Разумеется если вы не, скажем, в Англии или, например, у вас не стоят солнечные панели. А то, знаете-ли, не далее как этой весной у соседа коллеги по работе с участка вывозили труп рабочего, что в яркий солнечный день устанавливал солнечные панели...

ЕМ>Если нужен метод, попробуйте хотя бы навскидку прикинуть количество всех возможных состояний всех элементов любого эпизода DOOM, подлежащих обработке. Текстуры, угол зрения, источники света, расположение предметов, их состояние, тенденции и т.п. Если знаете способы запихать все это хотя бы в единицы килобайт, то можете честно портировать кусок игры хотя бы на ATMega328, станете идолом всех айтишников планеты. Я серьезно.


идолы всех айтишников планеты где-то рядом.

BFE>>И какая польза от такого патента? Поди вред один...

ЕМ>Я правильно понимаю, что все Ваши познания о патентной системе почерпнуты из срачей о патентных троллях?
Сам автором патентов не являюсь, но в написании принимал участие.
И каждый день — без права на ошибку...
Re[26]: Об эффективности виртуальных функций
От: scf  
Дата: 22.08.24 17:54
Оценка:
Здравствуйте, B0FEE664, Вы писали:

BFE>Уж я бы точно не экономил на длине кабеля.

BFE>>>Причём тут проводка?
BFE>Конечно-конечно. Разумеется если вы не, скажем, в Англии или, например, у вас не стоят солнечные панели. А то, знаете-ли, не далее как этой весной у соседа коллеги по работе с участка вывозили труп рабочего, что в яркий солнечный день устанавливал солнечные панели...
BFE>идолы всех айтишников планеты где-то рядом.
BFE>Сам автором патентов не являюсь, но в написании принимал участие.

А здесь вы можете наблюдать типичную дискуссию на КЫВТе об эффективности виртуальных функций.
Re[26]: Об эффективности виртуальных функций
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 23.08.24 09:30
Оценка:
Здравствуйте, B0FEE664, Вы писали:

BFE>идолы всех айтишников планеты где-то рядом.


Их там нет. Это ж не "порт DOOM", а "игра в стиле DOOM". Это такой же DOOM, как простейший, "неподкидной" дурак — такая же "карточкая игра", что и покер/преферанс.

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

BFE>Сам автором патентов не являюсь, но в написании принимал участие.


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