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 вместо виртуальных ф-ций.


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