Владимир Закалык @Deohayer
Инженер встраеваемых систем
Information
- Rating
- Does not participate
- Location
- Львов, Львовская обл., Украина
- Date of birth
- Registered
- Activity
Specialization
Embedded Software Engineer, Application Developer
Middle
C++
Object-oriented design
Algorithms and data structures
C
Multiple thread
Изменение оператора++ это то, что я считаю реальной оптимизацией (точнее, здравым смыслом, но не будем об этом). А вот использовать статический или динамический массив - это другое уже. Тут надо буквально сделать две разных имплементации, подобрать пару десятков юзкейсов, которые используют разные сценарии (в том числе явные перемещения, xvalue), измерить и сравнить. Конкретно эта задача для меня совсем не в приоритете, она уж слишком нишевая. Решение с динамическим массивом более универсально.
Ниже сказали, что перемещение "Leaves X in a valid but unspecified state".
Если вы всё же настаиваете, чтобы значение оставалось прежним, то извините, здравый смысл это здравый смысл. Для этого есть копирование. Хорошо, с этой точки зрения класс не ведёт себя как встроенный тип. Зато перемещение это действительно перемещение, а не простое копирование.
Повторю сюда тоже. Хорошо, переделаю так, чтобы после перемещения там был 0, и любое присваивание значения (из строки тоже) работало.
Нет, не думаю, что странновато. Просто разные взгляды. Почему я считаю, что надо использовать динамику:
Забирать столько стековой памяти - плохо. Просто потому что я ловил предупреждения о её переиспользовании в ходе разработки. Из-за других причин, но ограничения есть!
Моя библиотека не об экономии на спичках. За этим, ещё раз, к GNU MP.
Адекватная реализация взаимодействия с базовыми типами, а не как сейчас, - ОК. Оптимизация алгоритмов - ОК. Реализация на стеке, хипе, и с кастомной аллокацией, чтобы угодить всем, - уже не ОК, так как это несколько разных библиотек надо написать.
Дальше я буду добавлять типы с динамическим размером. Их точно в стек не засунешь, и они отлично вписываются в уже существующую реализацию.
Согласен, я могу слегка изменить код и гарантировать, что эту переменную можно использовать дальше, она будет иметь значение 0.
Звучит как интересный и эффективный подход. Можете поделиться источниками о скрининг-собеседованиях, которые вы использовали?
Обработку такой ситуации можно добавить. Хотя если такое произошло, то у вас в системе явно проблемы посерьёзнее.
Возможно будет, возможно нет. Зависит от того, насколько это будет нужно.
Таких "Где" для библиотек данного типа можно бесконечно придумать - по одному на каждый существующий юзкейс и алгоритм.
Если это проблема - то надо использовать GNU MP и больше ничего. Желательно вообще ничего не использовать, а прямо на ассемблере писать. И я сейчас без сарказма, вполне могу представить себе RTOS или что-то подобное, где частое обращение по указателю было бы проблемой.
А ещё оператор sizeof() у меня неправильно возвращает количество байт :)
Экономлю 4096 / 8 = 512 байт (RSA). Ну, около того.
Если после
std::move
к xvalue переменной всё ещё можно обращаться для чтения значения, то это копирование, а не перемещение, вне зависимости от того, базовый тип это или объект. Если я неправ, то скиньте, пожалуйста, где в стандарте это сказано (любой, от 11 до 20). Возможно, я пропустил.Я эти функции использую для выделения памяти под массив базовых типов, POD. В стандарте указано, что функция стандартной же библиотеки - UB?
Нет, это оптимизация работы с памятью!) Всё ради
realloc
. В будущем будет полезно, так как будут ещё и саморасширяющиеся типы (грубо говоря бесконечные), о них много вопросов было.А сейчас, например, это позволяет оптимизировать операции перемещения (move) между целыми разных размеров:
Вместо аллоцирования через new (make_unique) и копирования, просто переставляется указатель, а размер массива урезается при помощи
realloc
. Ну и если наоборот, слева размер больше, справа - меньше, то есть неплохой шанс, чтоrealloc
увеличит массив без копирования. И как приятный бонус: если копирование произошло, мне не надо делать никаких дополнительных вызовов или циклов для копирования,realloc
всё сделал за меня.Буду рад советам, как динамическую аллокацию можно реализовать лучше. Или чуть более детальному объяснению, чем плохи эти аллокаторы.
Для header-only надо один include, для компиляции надо этот же include, плюс что-то компилировать. Даже если будет CMake, GNU Make, любая автоматизация этого процесса - надо будет ещё где-то тыкануть строку "вызови вот это вот". И прочитать о том, что нужно тыкануть эту строку. Для меня это минус - я ленивый, и хочу дать возможность таким же ленивым людям не делать лишних телодвижений при работе с библиотекой. При этом я не хочу обижать тех, кто знает о недостатках header-only подхода. Вот почему компиляция не просто "есть или нет" - она опциональна.
Контекстуально. Первой - популярный компилятор на Linux, второй - на Windows. "Я проверил компиляцию на двух ОС и сделал это вот такими компиляторами". Нет, кроме этих ни на чём другом не пробовал, признаюсь сразу. Обязательно попробую.
Да, об этом отдельный пункт есть "Режим компиляции исходников". Если задефайнить
AP_USE_SOURCES
то нужно будет скомпилировать все .cpp файлы библиотеки, без каких-либо нюансов.Потому что я не проверял поддержку С++20 и, скорее всего, не работает. Упомянуто в пункте "Что в планах".
Нет интеграций со системами сборки, так как интеграция тривиальна - нужно скачать репозиторий и добавить его в проект. "Добавить в проект" - расположить папку там, где хочется, опционально добавив её в include path. Если хочется компиляции - всё то же самое, плюс глобнуть все .cpp файлы, что делается одной строчкой в GNU Make / CMake. Для Visual Studio - пара кликов, он сама знает, что делать с .cpp.
Это расписано в пункте "Тестирование". Есть чёткая система генерации операндов, она создаёт всевозможные сценарии комбинаций операндов, включая специфичные случаи (ноль, максимум, минимум, один, минус один).
Тут оправдываться не могу. Документацию надо будет сделать.
Условная компиляция и вперёд. Не так красиво, как одна функция на все случаи жизни, конечно. Но гибкость важнее.
Да, школьная классика уже работать не будет, и для случаев, когда скорость важна, есть GNU MP. Я не хочу соревноваться в скорости с библиотекой, которую разрабатывали десятки лет (точно проиграю), да и не нужно. Тривиальные вещи, вроде умножения Карацубы, - это без проблем.
Ну тогда всё отлично, корректное поведение.
Спасибо!
Не показатель. В Boost это просто использование __int128. slimcpplib тоже знает об этом типе. Надо смотреть что-то более показательное, хотя бы 4096, и запустить несколько тысяч раз хотя бы. Я этим займусь через пару недель :)
Всё просто: нам мало int, который даёт C++, мы дописываем свой, побольше, но так, чтобы было не отличить от настоящего, маленького. И в нём должно быть что-то для каждого. Всё, для чего есть несколько точек зрения, должно быть настраиваемым. Исключение: представление знаковых. Тут мимикрия под дополнительный код и арифметический сдвиг. Во-первых, это распространено, C++20 тому подтверждение (наконец-то!). Во-вторых, настраиваемость представления и поведения знаковых банально усложнит поддержку и тестирование, и всё ради опции, которая почти никому не нужна.
Должны быть и фиксированные, и свободно расширяющиеся инты. И стековая и динамическая память. И со знаком, и без знака. И с исключениями при переполнениях и делении на ноль, и без. И всё в таком духе дальше.
Операторы и конструкторы большого целого должны спокойно работать с обычными целыми, без явного приведения типа снаружи (да и внутри, желательно, ради скорости).
Тут не constexpr главный, а std::array, потому что с динамическим массивом это не работает. Но даже это можно добавить, сначала нужно реализовать большое целое на стеке, а дальше макросы наше всё: ap_linkage, ap_constexpr...
Ну и "человеческий интерфейс" - громковато для возможности посчитать константу во время компиляции и задать значение без кавычек. Безусловно интересная, хорошая возможность, есть свои области применения, но и без неё интерфейс останется человеческим.
Дисклеймер: конечно же это всё звучит "сейчас ничего нет, но вот когда-то я всё сделаю". Но мне нужен ранний фидбек, чтобы понять, куда двигаться дальше и что учесть при дальнейшей разработке.
С ним ещё sizeof() правильно работать будет, тоже важно.
Спасибо, надо будет посмотреть. Постоянно сравнивать со всевозможными конкурентами неплохо так съедает время. Похоже, нужно написать фреймворк для анализа библиотеки такого типа, т. е. учитывать корректность работы, быстродействие и наличие конкретных элементов интерфейса (операторов и конструкторов). Всё равно хотел что-то подобное сделать, чтобы иметь возможность оценивать прогресс между версиями.
В slimcpplib использование std::array настораживает. И из-за этого интересует быстродействие.
Header-only это хорошо и удобно, все счастливы. "А сколько весит билд и длится компиляция?". После этих слов в программистском поезде начинается сущий кошмар.
constexpr - интересно, хорошо, что есть. По крайней мере, можно посчитать константы. Если они часто используются, то это неплохая оптимизация. То же решето Эратосфена - сохранить столько, сколько можно.
Если брать откровенную вкусовщину без анализа, то:
Как сделать динамический инт (без указывания размера). У меня тоже нет, и мне на это указывали.
std::array подразумевает много копирования.
Нет побитовых операторов для знакового. "Не решайте за меня, что мне не нужно".
Нет интерфейса для взаимодействия с базовым целым (если я не пропустил).
Только С++17. А 11, 14 и 17 одинаково популярны.
Почему только header-only.