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 по-разному реализованы и так же имеют свои особенности.