Маша С++
104 subscribers
54 photos
2 files
65 links
Учу C++ и не только вместе с вами, мои котятки)
Download Telegram
Интересная научная статья фокусируется именно на потреблении энергии (CPU + RAM) в дополнении к памяти и времени работы. Авторы сравнивают 27 популярных языков программирования, замеряя потребленные Джоули при решении 10 задач. Замер потребления энергии производится с помощью утилиты Intel’s Running Average Power Limit.

В финальной таблице (см пост ниже) по всем задачам можно например заметить как Java потребляет в 5 раз больше рамы, чем Си. По потреблению энергии и по времени работы в первой тройке C, Rust и C++. Примечательно, что Rust почти не отличается от C, а вот C++ отстает на 30-50%. В статье приводятся результаты для трех задач: binary-trees (выделение, обход и удаление множества двоичных деревьев), fannkuch-redux (индексируемый доступ к крохотным последовательностям интов) и fasta (генерация и запись случайных последовательностей ДНК). В первых двух задачах лидируют C/C++, в третьей же - Rust, при этом C++ в ней довольно заметно отстает. С чем это связано не понятно, возможно на плюсах медленнее вывод в файл или генератор случайных чисел. Ставить под сомнение сводные результаты 10 задач на основе данных по 3 я не буду.

Интересно, что Python уверенно занимает предпоследнюю строчку и в 70 раз "хуже" Си. Спасай природу, переписывай свой питон код на Си 😁

Полный текст статьи: https://haslab.github.io/SAFER/scp21.pdf

#cpp #rust #performance
🔥2
"did everybody expect that to happen?" спрашивает докладчик. Такого уж я точно не ожидала. Он сравнил ускорение (speedup на легенде) двух приложений: wait-free находит сумму через std::atomic, в то время как mutex находит ту же сумму, используя одноименную блокировку и обычные (неатомарные) переменные.
Внезапно оказалось, что wait-free масштабируется значительно хуже простого mutex.
Детали и более подробное устройство атомиков тут: https://www.youtube.com/watch?v=ZQFzMfHIxng
#cpp #multithreading
Вот нельзя было в плюсах в контейнерах вместо empty() использовать isEmpty() ? Первое вполне себе глагол/действие...
#cpp
Пример простой, но при этом достаточно эффективной реализации многопоточного паттерна event loop. Да на хабре, да на английском. Используется std::function для задач, std::condition_variable.

https://habr.com/ru/articles/665730/

#cpp #multithreading #habr
👍1
В std::list метод erase() возвращает итератор, следующий за удаленным элементом.
Почему? Ну во-первых итератор на удаленный элемент не валиден (он ведь удален), а во вторых это позволяет например организовать удаление из списка в цикле, вот так (1):
    std::list<int> lst = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
auto it = lst.begin();
while ( it != lst.end() ) {
if ( *it % 2 ) {
it = lst.erase(it); // (1) верно
//lst.erase(it); ++it; // (2) не верно
//lst.erase(it++); // (3) верно
} else {
++it;
}
}
Вариант (2) упадет (почему?), вариант (3) тоже рабочий, но возможно более сложный для понимания, чем (1)
#cpp
std::list, обычно реализуемый как двусвязный список, имеет метод вставки элемента в начало push_front(). Понятно, что для двусвязного списка эта операция константна.

Разработчики же интерфейса std::vector предусмотрительно не стали реализовывать метод push_front(), так как добавление элемента в начало массива влечет необходимость переместить все элементы, а это уже O(n).
Однако вставить элемент в начало вектора все же можно, для этого следует воспользоваться методом insert():
    std::vector<int> v;
for (int i = 0; i < 5; ++i) {
v.insert(v.begin(), i);
}
// v = {4, 3, 2, 1, 0}

#cpp
🔥1
Добавленный в C++11 std::forward_list реализует односвязный список, в отличие от двухсвязного std::list, и потому занимает меньше памяти. Однако за это приходится своеобразно платить. Допустим, мы находимся на элементе 3 и хотим его удалить. Для этого нужно изменить связь предыдущего элемента 2, но мы не можем к нему вернуться, так как связь идет в одну сторону (в двухсвязном в обе). Поэтому методы добавления и удаления элементов в forward_list изменяют элемент после указанного, так что мы можем обновить ссылку. Для этого в таком списке используется например не метод erase (которого вообще нет), а метод erase_after.

А что же делать с первым элементом, спросите вы, мои котятки? Как его удалить, если erase_after(begin) удалит элемент после первого, то есть второй? Для этого разработчики придумали интересный костыль, а именно метод before_begin(), который возвращает итератор на несуществующий элемент перед первым (аналогично тому, как во всех контейнерах end() указывает на несуществующий элемент после последнего). Вот так вот 😉.

#cpp
👍3
Найдите ошибку:
    std::vector<int> vec = {0,1,2,3,4,5,6,7,8,9};
auto mid = vec.cbegin() + 5;
auto findIt = std::find(vec.cbegin(), mid, 10);
if (findIt == vec.cend()) {
std::cout << "Not found";
} else {
std::cout << "Found";
}
Ошибочно выведется "Found", хотя 10 нет в векторе. Почему? Дело в том, что std::find не возвращает итератор end контейнера, если элемент не найден (указатель на end попросту негде взять). Вернет же функция второй параметр (last), если элемент не обнаружен. Правильно бы было сравнивать в if с mid (который не просматривается, к слову).

#cpp
👍2
Часто бывает, что большой жирный класс реализует несколько интерфейсов и можно запутаться к какому именно принадлежит виртуальный метод. Было бы здорово, если имена методов можно было предварять именем интерфейса. Мне кажется, что это бы повысило читаемость. А может быть можно использовать для разрешения конфликта одинаковых имен от разных интерфейсов?

Или что-то такое уже есть?

class Foo : public Interface, public Callback
{
public:
virtual bool Interface::start() override {}

virtual void Callback::onData() override {}
};

#cpp
Вышел Qt 6.6. Изменения, конечно, забавные. Если улучшение модуля Qt TextToSpeech еще с точки зрения UI-фреймворка как-то можно понять (поддержка людей с ограниченными возможностями из коробки это хорошо), то вот добавление какой-то СУБД Mimer SQL (ни разу не слышала про такую), добавление класса для захвата содержимого отдельного окна QWindowCapture и тп вызывает ощущение дикого раздувания фреймворка. Лучше бы Qt Widgets полировали. (А вообще, конечно, кьют - ванлав 🫶).

https://www.opennet.ru/opennews/art.shtml?num=59907

#cpp #qt