LINUX.ORG.RU

C++ — туда и обратно, или зачем нужен Boost

 , , ,


3

5

Мой предыдущий тред в Development собрал самое большое число ответов аж с сентября, то есть за последние 9 месяцев, и это лишний раз подтверждает упадок этого форума. Полагаю, кто-то должен это изменить, и поэтому мы с тобой, ЛОР, поговорим сегодня про C++.

Начиная с C++26 вместо std::function вводится пачка новых классов: std::copyable_function, std::move_only_function (доступна с C++23) и std::function_ref. Что же не так с оригинальным std::function, ты можешь спросить? А вот что:

#include <functional>
#include <print>

struct call_me {
    int x = 0;
    void operator()() {
        std::print("x was {}\n", x++);
    }
};

int main() {
    const std::function<void()> f = call_me{};
    f();
}

Несмотря на то, что переменная f объявлена константной (люблю оксюмороны!), у неё есть внутреннее состояние и оно меняется при вызовах. Компилятор это без проблем хавает.

Так вот, ковыряясь в том, зачем и кто вообще смог так насрать себе в штаны сам, я наткнулся на статью ребят, которые подводят список подобных косяков комитета C++, когда фичи живут по 10 лет и объявляются устаревшими.

Небольшой список фич, которые были придуманы, оказались не нужны/бесполезны/вредны и выкинуты:

  • Известный vector<bool>, живущий издревле в STL и про который все говорят, что его надо избегать. Частично заменяется std::bitset.
  • std::auto_ptr. Бесполезен, ломает контейнеры, выкинут на помойку в C++17.
  • Указание исключений у функции в формате throw(X, Y). Так же выкинуто в C++17.
  • std::iterator объявили устаревшим в C++17, собираются удалить в C++26.
  • std::aligned_storage и std::aligned_union добавлены в C++11, объявлены устаревшими в C++23, скоро удалят.
  • Ключевое слово register удалено в C++17, хотя всё ещё доступно в Си.
  • std::get_temporary_buffer и std::raw_storage_iterator удалены в C++20.
  • Потрясающее по эпичности фиаско с интерфейсом для сборщиков мусора. std::declare_reachable сотоварищи были добавлены в C++11. Выяснилось, что сборщики мусора для C++ писать либо никто не умеет, либо никто не хочет, поэтому в C++23 это всё удалили и сделали вид, что ничего не было.
  • Абсолютное безумие вокруг концептов, модулей и поддержки сети. Предложения одобряли, вновь отклоняли, переделывали, и по итогу теми же модулями до сих пор никто не пользуется.
  • Сопрограммы (coroutines). В том виде, в котором они есть в C++, это просто ужас. Достаточно того, что корутины требуют выделения памяти из кучи во время работы, а значит вообще не подходят для случаях, когда требуется серьёзная производительность. Например, в любом коде, требующим работы в реальном времени и не позволяющем делать системные вызовы.

Просто лютый трешак, который никто подчищать пока не собирается:

  • std::regex – лютый тормоз, рекомендуется не использовать.
  • Мертворождённый std::simd, добавленный в C++26 и уже с ходу не нужный вообще никому, потому что код с std::simd в два-три раза тормознее чем со сторонними библиотеками, просто голыми интринсиками, и даже медленнее чем просто цикл for.
  • std::async. Дескруктор ждёт завершения асинка и поэтому может залочить весь код тебе. Наконец починили в C++26, но эта штука была сломана 15 лет.
  • Отвратительно спроектированный <iostream>. Его наконец можно выкинуть и использовать std::print, но не все про это знают.
  • Абсолютно тормозные контейнеры map, set, unordered_map. Вместо первого можно использовать flat_map из C++23. Контейнеры в стандартной библиотеке Rust (BTreeMap) и другие реализации B-Tree Map их обгоняют по производительности, но тем не менее в C++ выбирают убогий дефолт.

Решения многих из этих проблем существуют в Boost и сделаны там гораздо лучше. Но в то же время возникает важный вопрос: зачем вообще нужен настолько плохо спроектированный язык, где каждое следующее поколение инженеров, работающих над ним, отменяет решения предыдущих, а код под новые стандарты часто нужно переписывать если не с нуля, то очень близко к тому? Даже процесс разработки Rust с его поехавшими клоунами в юбках на этом фоне выглядит адекватным.

В общем, всё печально, ЛОР. Такие дела.



Последнее исправление: CrX (всего исправлений: 3)
Ответ на: комментарий от zurg

Никто, никогда не забывает ставить copy,

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

бывают типы которые нельзя копировать

Частный случай, 0,00001%.

Внимание вопрос: зачем язык как дефолтную конструкцию рассматривает 0,00001%, а в остальных 99,9(9)% погромизд должен копипастить семантический мусор?

r--r--r--
()
Ответ на: комментарий от yorshka

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

В продолжающей работать программе.

В Rust же почти никто паники не перехватывает и, соответственно, последствия от паники в drop куда мягче.

Программа тупо падает, да.

r--r--r--
()
Ответ на: комментарий от eao197

В C++ использование try{} catch() {} является чуть ли не повсеместным

Похоже, все зависит от того, кто куда и как смотрит.

Если ты работаешь на гугель и весь код собирается с -fno-exceptions, вопросов конечно нет. Но это редкость. В среднем, в проектах, с которыми я работал, исключения достаточно часто использовались как часть control flow, особенно в более старом коде (до C++11).

yorshka
() автор топика
Ответ на: комментарий от yorshka

В среднем, в проектах, с которыми я работал, исключения достаточно часто использовались как часть control flow,

Я специально поискал catch в своем проекте. Всего лишь несколько десятков вхождений на 37KLOC кода.

eao197 ★★★★★
()
Ответ на: комментарий от yorshka

в проектах, с которыми я работал, исключения достаточно часто использовались как часть control flow

Я даже на java такого не видел.

r--r--r--
()
Ответ на: комментарий от eao197

Весь этот набор банальностей не отвечает на заданные мной вопросы.

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

Возможно, это сообщение тебе тоже покажется банальным.

Darfin
()
Ответ на: комментарий от eao197

В среднем, в проектах, с которыми я работал, исключения достаточно часто использовались как часть control flow,

Я специально поискал catch в своем проекте. Всего лишь несколько десятков вхождений на 37KLOC кода.

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

Тем не менее, в Rust при написании реализации drop программисту не нужно думать что какая-то из вызванных функций запаникует, если это явно не является частью API (например, .unwrap(), за который надо по рукам бить), потому что паника является аварийной ситуацией. В случае с C++, стоит рассчитывать, что любая посторонняя функция может кинуть исключение.

TL;DR не надо сравнивать панику и исключения в C++. Это разные механизмы для разных целей.

yorshka
() автор топика
Ответ на: комментарий от Darfin

Возможно, это сообщение тебе тоже покажется банальным.

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

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

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

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

r--r--r--
()
Ответ на: комментарий от yorshka

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

Я, собственно, сразу об этом и сказал:

все зависит от того, кто куда и как смотрит.


TL;DR не надо сравнивать панику и исключения в C++.

Я не сравниваю панику с исключениями. Я сравниваю количество знаний, которые нужны в C++ для написания деструктора, с количеством знаний, которые нужны в Rust-е для написания Drop::drop.

eao197 ★★★★★
()
Ответ на: комментарий от r--r--r--

И в чём же фундаментальная разница?

Документацию почитай, хотя бы:

https://doc.rust-lang.org/reference/panic.html

Например, в том, что бесконечный цикл при панике – вполне валидная реализация.

yorshka
() автор топика
Ответ на: комментарий от eao197

Я сравниваю количество знаний, которые нужны в C++ для написания деструктора, с количеством знаний, которые нужны в Rust-е для написания Drop::drop.

Окей. В C++ этих знаний требуется больше.

yorshka
() автор топика
Ответ на: комментарий от yorshka

бесконечный цикл при панике – вполне валидная реализация.

Но это не разница между throw и panic!(). Это разница между крестами и растом.

Давай я переформулирую вопрос.

Дано:

Пишем обработчик http-запроса, в ходе которого фетчим предзагруженные данные в бд. В ходе обработки, у нас возможны три сценария ошибок:

  1. Ошибка на вводе / ввыводе с БД
  2. Ошибка структуры БД
  3. В БД нет pre seed данных

API на все операции корректно возвращает Result / Option.

Вопрос:

Будешь ли ты делать unwrap()?

r--r--r--
()
Ответ на: комментарий от r--r--r--

https://godbolt.org/z/j1rc31h8d я буду использовать С++, потомучто в нём есть наследование, а Раст не серьезный язык, даже с такой тулой, факт заключается в том, что С просуществовал в еще более худшем состоянии, когда Раст не осилел наследование, но в тот же момент осилил борова

anonymous
()
Ответ на: комментарий от eao197

получается одна из нюансов С++ и Раста

https://godbolt.org/z/abdY6MTKz С++

https://godbolt.org/z/ersj5hdT4 Раст

как по мне проблема очевиднее между двумя языками чем может показаться, когда начнём проектировать на Расте, когда на С++ проектирование удобнее получается нагляднее чтоли, дело не в методе дроп или деструктор, но С с деструктором было бы вау и классно сегодня )

anonymous
()
Ответ на: комментарий от zurg

понимаете в чем дело, вот мы начинаем путь - изучаем кодинх, вот например С/С++, вдруг появляется Раст, по началу прикольно, но попользовавшись такими удобствами начинаешь понимать, что Раст крут да? конечно, никто не спорит, но во первых Раст нельзя отключить и включить своё видение, на С++ есть больше опций для реализации своего видения, прибавив сюда тонкости того что зачерпнули в Расте, возвращаемся на С++ с уже осознанными запросами к языку и более менее становится понятно, что то что предлагает Раст не панацея, а взгляд одного из. Получается С++ просто шире, наследование покрывает нужные задачи где он просто обязателен и он не костыльный как весь ООП в С++ после кодинга на Расте, а в Расте это портянки и компизиции бесконечные. А ну еще нюансы FFI. Ну да многопоточка ваще улётная, но после Раста реально на С++ смотришь не так как до захода в Раст.

а по тому что мол костылинг, есть же вроде std::optional

anonymous
()
Ответ на: комментарий от r--r--r--

Но это не разница между throw и panic!(). Это разница между крестами и растом.

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

Будешь ли ты делать unwrap()?

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

yorshka
() автор топика
Ответ на: комментарий от anonymous

если я правильно понимаю, алгебраические типы в С++ можно просто создать свои выделить их в группу математических, тоесть отделив от строк и буквенных значений, и просто вывести нужное поведение, в Расте да удобно в этом плане тыкнул в инпут нужного вывода библиотеки и провел тип и поведение, но опять же реализовывая BVH на обоих языках с минимальными возможностями в 3д код работает абсолютно индентично по моим ощущениям, да для стриминга и многопотока придётся вникнуть в мутексы и локи возможно, но я считаю это обоснованная плата входа, потомучто всё до стриминга вполне реализуемо, а это самое начало технологий только, там что не рассматривай на старте хоть бвх хоть бсп, они почти одинаковы по реализациям будут, но реализация УИ на композиции - извините, пока не попробуешь дерево, конечно интересно, но после ООП на УИ глядя как оно работает, компизиции писать вообще нету желания.

anonymous
()
Ответ на: комментарий от r--r--r--

Будешь ли ты делать unwrap()?

Конечно же нет.

А что ты будешь делать? Вот вернул тебе сиквель запрос ошибку. Твои действия?

Очень странный вопрос, чувак.

Встречный вопрос: вернул тебе read() в сишной проге ошибку. Что ты будешь делать? Падать в кору?

yorshka
() автор топика
Ответ на: комментарий от yorshka

а тут нюансы есть, предположим байты не потерялись от С, которые пришли в Раст, где-то читал, что байты могут потеряться, типо С кидает строку, а Раст на приёме потерял что-то. А в событийной модели красивее, кд, события и прочее, наверно это и есть control flow.

anonymous
()
Ответ на: комментарий от yorshka

вернул тебе read() в сишной проге ошибку. Что ты будешь делать?

Разверну стэк вызовов обратно с кодом ошибки до точки, где ошибку имеет смысл обработать.

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

Ввернул тебе сиквель запрос ошибку. Твои действия?

r--r--r--
()
Ответ на: комментарий от r--r--r--

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

Ввернул тебе сиквель запрос ошибку. Твои действия?

Ну вот ровно так же и сделаю:

Разверну стэк вызовов обратно с кодом ошибки до точки, где ошибку имеет смысл обработать.

Только вместо ручного сишного if(err != 0) return err; в Rust есть Result и оператор ?. А в остальном суть та же.

yorshka
() автор топика
Ответ на: комментарий от yorshka

Ну вот ровно так же и сделаю:

Что ты сделаешь-то, я не понял нихера. Ты пишешь код обработчика. Никакого контроля над кодом по стеку выше у тебя нет. API обработчика требует вернуть из функции объект с ответом. Как вариант, можешь вернуть экземлпяр impl Responder / Writable. Твой err клиенту в браузере нахер не упёрся.

в Rust есть Result

Тебе ещё Option обрабатывать надо.

и оператор ?.

Который чем тебе поможет?

Ты, я так чувствую, с растом только по срачам на лоре знаком?

r--r--r--
()
Ответ на: комментарий от r--r--r--

Никакого контроля над кодом по стеку выше у тебя нет. API обработчика требует вернуть из функции объект с ответом. Как вариант, можешь вернуть экземлпяр impl Responder / Writable. Твой err клиенту в браузере нахер не упёрся.

Ну, значит единственный вариант тут – записать в лог и вернуть 500.

Тебе ещё Option обрабатывать надо.

И в чём проблема?

Ты, я так чувствую, с растом только по срачам на лоре знаком?

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

yorshka
() автор топика
Ответ на: комментарий от yorshka

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

anonymous
()
Ответ на: комментарий от anonymous

с вэб мордой можно пойти по пути как Ipython, предположим есть утилита которая создаёт шаблон проекта для С++, она может создать шаблон, добавлять модуль, добавлять библиотеку в зависимость, собирать и запускать, очевидно она на разметке какой-то, можно эту разметку докрутить до HTML, тоесть состояние и команды проекта рисовать в вэбэ например )…

anonymous
()
Ответ на: комментарий от BruteForce

Корректность и эффективность использования без необходимости гадать - «а не провиснут ли итераторы/ссылки из-за того что внутри что-то перевыделится». В растовых - клиенту достаточно ориентироваться только на внешний интерфейс. Плюсовые типы так не умеют, в смысле, эффективно локализовать UB-шные эффекты. Чего ни как не поймут мракобесы вроде чувака выше с шизофазией - «лол, кек, азаза, в друсте нету списков».

zurg ★★
()
Ответ на: комментарий от anonymous
<?xml version="1.0"?>
<package>
    <meta name="GameEngine1" version="1.0.0" type="application" />
    <compiler path="clang++-20" standard="23" optimization="2">
        <stdlib value="libc++" />
        <std_module_path value="/usr/lib/llvm-20/share/libc++/v1/std.cppm" />
        <flags>
            <flag value="-Wall" />
            <flag value="-Wextra" />
            <flag value="-Wno-unused-command-line-argument" />
        </flags>
        <links />
        <lsp>
            <arg value="      -std=c++23," />
            <arg value="      -stdlib=libc++," />
            <arg value="      -Iinclude," />
            <arg value="      -I/usr/lib/llvm-20/share/libc++/v1," />
            <arg value="      -fmodule-file=std=../bin/std.pcm," />
            <arg value="      -fmodule-file=Math=../bin/Math.pcm," />
        </lsp>
        <lib>
            <links name="assimp" />
        </lib>
    </compiler>
    <structure>
        <dir path="src" type="sources" />
        <dir path="include" type="headers" />
        <dir path="bin" type="output" />
        <dir path="assets" type="resources" />
        <dir path="modules" type="modules" />
        <dir path="ThirdParty" type="dep" />
        <dir path="dep_dirs_comp" type="dep" />
        <dir path="modules" type="modules" />
    </structure>
    <dependencies>
        <lib name="assimp" url="..." version="latest" cmake_flags="" />
    </dependencies>
</package>

типо такого получается, зато прикол в том, что не надо ручками править клангд )

anonymous
()
Ответ на: комментарий от ckotctvo

у меня есть хитрожопое дерево и хитрожопый список.

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

zurg ★★
()
Ответ на: комментарий от zurg

переписал в лоб на хэшмапах вообще не задумываясь об оптимизации и … обошёл свою «оптимизированную» сишную версию процентов на 20-30 (точно не помню, но порядок такой).

Подскажите хороший алгоритм хеширования значений слов.

anonymous
()
Ответ на: комментарий от zurg

а в расте нельзя локализовать разыменование unsafe *const T который смотрит на С, получается, на стадии отладки будут тоже баги, пока пишешь свои ответные интерфейсы к С интерфейсам если стремиться к нулевой зависимости, чтобы не качалось лишнего.

anonymous
()
Ответ на: комментарий от anonymous

хочется добавить со всей простотой Раста, наличие хотябы одного ’a например в структуре вешает brain-time типо надо всегда помнить об этом, и надо понимать борова, кароче в Расте свои приколы и их полно, понимаю что список нужен как таковой, но по большей части можно обойтись вектором, кароче получается если абстрагироваться в Расте не меньше ментальной гимнастики + отсутствие адекватного наследования, можно зайти в свою зеро-депенденси библиотеку или модуль, и просто потеряться как в С.

anonymous
()
Ответ на: комментарий от yorshka

Ты формулируешь дико абстрактные вопросы,

Как имплементация конкретных трейтов для salvo, actix, rocket или axum может быть "дико абстрактной", норкоман?

контекст к которым есть только у тебя в голове

Он есть вообще в голове у любого, кто писал код на расте сложнее приветмира.

единственный вариант тут – записать в лог и вернуть 500.

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

Правильный ответ на вопросы выше - во всех случаях нужно кинуть панику, и 500 в одной точке кода отдаст клиенту перехватывающий панику middleware.

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

r--r--r--
()
Ответ на: комментарий от zurg

а если мне бывает нужно подвинуть в памяти много объектов не меняя их порядковый номер, как мне их искать по этому номеру?

boost::intrusive_rbtree и его дружбаны не позволяют этого делать из коробки, их надо дорабатывать. Но это хотя бы можно, идем в доку в раздел «Node algorithms with custom NodeTraits» и делаем там свою реализацию итератора, который можно подвинуть после изменения адреса. PROFIT!

а stlные какахи так не могут, еще и память аллоцируют постоянно.

ckotctvo
()
Ответ на: комментарий от r--r--r--

Как имплементация конкретных трейтов для salvo, actix, rocket или axum может быть «дико абстрактной», норкоман?

При том, что ты про них не упоминал.

Он есть вообще в голове у любого, кто писал код на расте сложнее приветмира.

Сорян, я не пишу вебню. Тем более на расте. Мне это не интересно.

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

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

А альтернативная реализация с вечным циклом для какой-то уембед платформы остаётся проблемой разрабов под эту платформу.

«Альтернативная», поддерживаемая прямо из коробки для всех платформ:

[profile.release]
panic = 'abort'
yorshka
() автор топика
Ответ на: комментарий от yorshka

Сорян, я не пишу

Да это уже понятно.

веб-макаки не умеют не говнокодить

Но всё ещё говнокодят лучше, чем ты со своими 100500 копипастами.

поддерживаемая прямо из коробки для всех платформ

Так раст в теории и работу с no_std "поддерживает", но все мы знаем, что это за поддержка.

r--r--r--
()
Ответ на: комментарий от r--r--r--

веб-макаки не умеют не говнокодить

Но всё ещё говнокодят лучше, чем ты со своими 100500 копипастами.

Судя по общему состоянию индустрии, нет. Судя по тому, что они решили использовать panic! как стандартный – по твоим словам, мне это доподлинно неизвестно – метод обработки ошибок (хотя в документации написано, что так делать не стоит), всё очень и очень херово.

поддерживаемая прямо из коробки для всех платформ

Так раст в теории и работу с no_std «поддерживает», но все мы знаем, что это за поддержка.

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

yorshka
() автор топика

и это лишний раз подтверждает упадок этого форума

Логика не ясна.
Непонятно, как большое количество комментариев демонстрирует упадок форума.

Saakx
()
Ответ на: комментарий от zurg

Корректность и эффективность использования без необходимости гадать - «а не провиснут ли итераторы/ссылки из-за того что внутри что-то перевыделится».

Кажется, если ты не берёшь что-то случайное из интернетов, то обычно случаи «провисания итераторов» указываются?

Мой вопрос относился к категоричности «написать на плюсах невозможно», и меня интересует, какую именно гарантию дать не получится? То, что контейнеры STL в целом кал — это понятно.

BruteForce ★★★★
()
Ответ на: комментарий от zurg

Где я такое подаю? Но в практическом смысле таки победа - код получился намного прямее и читабельней сишной бажной лапши

Человек какие-то графы вычислял, и сначала реализовал на сишке. Всё по-красоте - списки на указателях и, вообще, оптимизировал как это полагается в сишке. Потом переписал на раст, и поначалу тоже закопался в RefCell-ах, не вывез, плюнул и переписал в лоб на хэшмапах вообще не задумываясь об оптимизации и … обошёл свою «оптимизированную» сишную версию процентов на 20-30 (точно не помню, но порядок такой).

Графы вычислял со списками на указателях — уже звучит странно. В «Алгоритмах» (3-е изд.) Кормена, Лейзерсона и Ко предлагают списки смежности для sparse графов и матрицы смежности для dense графов, проговаривая для первого случая, что нужен массив списков. При этом для любого графа известно, что для ориентированных графов сумма длин всех списков равна кол-ву вершин и в два раза больше для неориаентированного графа. Что также позволяет использовать один массив для представления «списков». На мой дилетантский взгляд, здесь не нужны ни списки (т.к. список смежности — это массив, два массива или массив массивов), ни указатели (т.к. для работы с массивами даже психически проще работать с индесками, а не с адресами и смещениями). При этом производить доп. аллокаций не нужно в обоих случаях, и даже у фанатов адресов+смещений указатели не «провиснут».

«Оптимизировал как это полагается в сишке» — я не очень понимаю, что это значит. В любом случае, похоже, что он оптимизировал очень неоптимальный выбор примитивов. Стоило ознакомиться со справочной литературой, ИМХО, прежде чем приступать к такому делу.

и переписал [списки] в лоб на хэшмапах вообще не задумываясь об оптимизации

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

Я, кстати, не оч понимаю зачем тут хешмап? Что там у него было ключом?

UPD: Полистал википедию, вижу такое: https://en.wikipedia.org/wiki/Sparse_matrix#Storage , где

  • Coordinate list — это три массива

  • CSR/CSC и Ко — это 3 массива

  • DOK, где как раз нужна мапа, не приспособлен для вычислений

  • LIL, где как раз «списки», тоже «another format good for incremental matrix construction», а не для проведения рассчетов.

BruteForce ★★★★
()
Последнее исправление: BruteForce (всего исправлений: 1)
Ответ на: комментарий от yorshka

В случае с C++, стоит рассчитывать, что любая посторонняя функция может кинуть исключение.

не надо сравнивать панику и исключения в C++. Это разные механизмы для разных целей.

ЦеПеПе — говно, и говно он в т.ч. потому, что плодит плохие практики. Почему он их плодит — вопрос отдельный, но здесь, например в случае, когда цепепешники используют ИСКЛЮЧЕНИЯ для вполне обыденных ситуаций, мы видим пример такой плохой практики.

Должна ли программа на цепепе воплощать плохие практики? На мой взгляд нет.

Способствует ли язык цепепе, сообщество цепепе программистов, литература по цепепе, цепеповые коучи и т. п. плохим практикам? на мой взгляд — да.

BruteForce ★★★★
()
  • Markdown
Пустая строка (два раза Enter) начинает новый абзац. Знак '>' в начале абзаца выделяет абзац курсивом цитирования.
Внимание: прочитайте описание разметки Markdown.
Используйте Ctrl-Enter для размещения комментария