Опять же возникает вопрос, что более вероятно - что все картины отдадут в макулатуру и на месте Эрмитажа сделают картофельное поле, или что сайт отключат за "неуплату" и держатели бирок пойдут лесом?
Да, картины-подделки бывают, но обратите внимание - вы говорите про единичные случаи, тогда как в случае с NFT под сомнение ставится само понятие как таковое.
Таким образом - делаем в cron ежеминутную задачу - отслеживать конкретный лог-файл на предмет ключевого слова/фразы/цифры и т.д.
Мне кажется, это одно из худших проявлений Hyrum's law. Мне было бы неприятно, если после релиза с изменением логов стали стучаться в личку и требовать вернуть их назад, а то не считается статистика за день. Настолько "разумную жизнь" на основе логов надо убирать как можно быстрее.
Это скорее реализация std::forward_list (односвязный список), чем std::list (двусвязный).
В C++ можно передать кастомный аллокатор, если нет желания использовать дефолтный.
Эта строка:
data: T,
Что насчет placement new? В вашем примере объект создается и только потом мувается в это место, но он мог бы сразу создаваться. Это "стиль C++" с С++11. Вместо этой строки должен быть растовый аналог std::aligned_storage<T>, а в методе push - perfect forwarding аргументов.
В сериализованном виде слово "Pepper" пропадет, но к сожалению я не так прочитал абзац (неправильно понял), посчитал что "Pepper" и есть "ключ" (по аналогии с JSON).
На самом деле в сериализованном представлении ключи выкинуты (остались значения), так как считается, что контрагент знает про тот же .proto файл и может с его помощью расшифровать бинарный поток. Без .proto файла бинарный поток понять человеку/программе невозможно, читабельны только string-поля.
Можно использовать другой способ, который займет столько же памяти.
Для удобства можно считать, что нас вершин 1024 штуки (степень двойки специально), нумерация от 0 до 1023 включительно.
Можно завести `std::array<int, 1024> keys` (ключи отсортированы) и `std::array <int, 1024> values`.
Поиск по ключу займет не более чем 10 сравнений, по одному биту каждый раз. Индексы ключей у нас от `0000000000` до `1111111111`, поэтому надо смотреть ключ посередине - по индексу `1000000000`. Если он больше, то единицу отнимаем. И потом смотрим следующий бит.
int some_key = XXX;
int index = 0;
for (int i = BYTES - 1; i >= 0; --i) {
if (some_key >= keys[index + (1 << i)]) {
index += (1 << i);
}
}
return value[index];
В C++ типы всех значений вычисляются в процессе компиляции и жестко фиксированы. "Тип" auto это просто синтаксический сахар, все равно это будет какой-то реальный фиксированный тип.
Все переменные/объекты занимают какое-то количество байт на стеке, и это количество нужно знать заранее, иначе, например, непонятно как вычислить размер stack frame у функции (ассемблеру нужно это знать).
Вот такого в C++ не будет скорее всего никогда:
auto list = create_list();
// ^^^ тип list вычислится в РАНТАЙМЕ,
// будет std::vector<int>/std::vector<std::string>/другой
Аналог того, что происходит в C#/Java, на C++ выглядит скорее как использование std::any, который аллоцирует нужное количество байт для объекта в куче (в отличие от стека, там необязательно знать объем выделяемой памяти в compile-time). Можно иметь один из типов в рантайме:
std::any create_list(int n) {
if (n == 0) {
return std::vector<int>();
} else if (n == 1) {
return std::vector<std::string>();
} else {
return std::vector<char>();
}
}
int main() {
int n;
std::cin >> n;
auto list = create_list(n);
if (list.type() == typeid(std::vector<int>)) {
std::cout << "got vector of int" << std::endl;
} else if (list.type() == typeid(std::vector<std::string>)) {
std::cout << "got vector of string" << std::endl;
} else if (list.type() == typeid(std::vector<char>)) {
std::cout << "got vector of char" << std::endl;
}
}
Пиши в хидерах код а-ля using namespace std; - коллеги скажут спасибо, за то что им не придется это писать в каждом .cpp!
Подключай как можно больше хидеров, чтобы каждый .cpp файл раскрывался в 1mln строк - коллеги скажут спасибо за то, что у них больше времени на перекур во время пересборки!
Функция должна вернуть больше чем одно значение? Есть крутой лайфхак - записывай результаты в указатель! Для трёх значений это int process(int arg, int* res2, int* res3).
У меня возник похожий вопрос - а сами студенты перед поступлением в распоряжение к топикстартеру в курсе о гарантированном no hire в Huawei/Intel/Nvidia/etc.?
Потому что в свое время я начал было проходить отбор к топикстартеру, так как в пределах факультета кафедра разрекламирована, но остановился на полпути. Про "договоренности" узнал из статьи.
Откуда такой миф, что заниматься "наукой" это нереально здорово, почти как быть сверхчеловеком?
Давайте представим - вы прямо сегодня изобрели лекарство от рака (или что-то подобное, иначе это не "наука", а просиживание штанов) и опубликовались в скопусе.
Вы теперь миллиардер? Нет, все сливки снимет братва с фармкомпаний и академическая мафия, а ты как ехал на маршрутке, так и будешь ехать дальше, ведь у тебя !ПРИЗВАНИЕ! работать за 14-20к.
Про студентов: а кто постановил, что они обязаны работать в науке, особенно под вами? От школьников в 10-11 классах ведь не ждут, что они будут вести уроки за учителей. Так и студенты - они идут в вуз ввиду отсутствия альтернатив (у 95% элементарно откосить от армии), а там у какой-то деловой колбасы на них "виды" в своих корыстных целях. Учитесь работать в рыночной экономике.
Скрипт хороший. Жаль только, что многие преподаватели (в основном еще видевшие живого Ленина) ОЧЕНЬ волнуются, если кто-то не слушает именно их пересказ учебника в 8:45, поэтому любят просить включать камеры, задавать рандомные вопросы рандомным людям в рандомное время, и так далее.
Было бы неплохо "из коробки" иметь возможность часть нового кода писать на Rust и связывать его с плюсами. C++ может использовать C, в котором другая система линковки, через extern "C". Почему бы не поддержать в компиляторах extern "Rust" ? Это дало бы буст к юзабельности Rust в реальных проектах и все вышеназванные проекты можно было бы перевезти постепенно.
В той же паре Java/Kotlin можно совершенно бесшовно вызывать код одного языка из другого языка.
Вы имеете в виду String и &str? Это практически аналоги std::string и std::string_view соответственно из плюсов, с такими же сферами применения. У этих двух типов сферы использования пересекаются, но есть случаи когда конкретный тип нужнее. В C++ и в Rust оба типа используются постоянно.
for (много раз) {
std::vector<int> out(NumOfValues);
std::iota(out.begin(), out.end(), 1);
}
Вызов resize не влияет совсем, так как размер вектора уже достаточный. Но во втором коде лишняя аллокация и деаллокация памяти, из-за чего второй вариант "типа" медленнее. Я поменял одну строку, результат эквивалентный: https://quick-bench.com/q/fSU3z97n18YhNGBgHmojrtW0Y0U
Опять же возникает вопрос, что более вероятно - что все картины отдадут в макулатуру и на месте Эрмитажа сделают картофельное поле, или что сайт отключат за "неуплату" и держатели бирок пойдут лесом?
Да, картины-подделки бывают, но обратите внимание - вы говорите про единичные случаи, тогда как в случае с NFT под сомнение ставится само понятие как таковое.
А чем современная банковская система не устраивает? Тем, что в ней намайнить бабла немножко сложнее, чем накупить асики и подключить к программке?
Мне кажется, это одно из худших проявлений Hyrum's law. Мне было бы неприятно, если после релиза с изменением логов стали стучаться в личку и требовать вернуть их назад, а то не считается статистика за день. Настолько "разумную жизнь" на основе логов надо убирать как можно быстрее.
Про "стиль C++" в списке, а именно про это
Это скорее реализация
std::forward_list
(односвязный список), чемstd::list
(двусвязный).В C++ можно передать кастомный аллокатор, если нет желания использовать дефолтный.
Эта строка:
Что насчет placement new? В вашем примере объект создается и только потом мувается в это место, но он мог бы сразу создаваться. Это "стиль C++" с С++11. Вместо этой строки должен быть растовый аналог std::aligned_storage<T>, а в методе
push
- perfect forwarding аргументов.Я имел в виду названия полей, то есть из записи
В сериализованном виде слово "Pepper" пропадет, но к сожалению я не так прочитал абзац (неправильно понял), посчитал что "Pepper" и есть "ключ" (по аналогии с JSON).
На самом деле в сериализованном представлении ключи выкинуты (остались значения), так как считается, что контрагент знает про тот же .proto файл и может с его помощью расшифровать бинарный поток. Без .proto файла бинарный поток понять человеку/программе невозможно, читабельны только string-поля.
Можно использовать другой способ, который займет столько же памяти.
Для удобства можно считать, что нас вершин 1024 штуки (степень двойки специально), нумерация от 0 до 1023 включительно.
Можно завести `std::array<int, 1024> keys` (ключи отсортированы) и `std::array <int, 1024> values`.
Поиск по ключу займет не более чем 10 сравнений, по одному биту каждый раз. Индексы ключей у нас от `0000000000` до `1111111111`, поэтому надо смотреть ключ посередине - по индексу `1000000000`. Если он больше, то единицу отнимаем. И потом смотрим следующий бит.
Да уж, это насколько же программисту надо плохо думать о разработчиках компиляторов, чтобы полагать, что
x /= 2
не заменится наx >>= 1
сам)Да, язык хорошо живет без рефлексии много лет, но новый функционал это новые возможности.
Можно подсмотреть, что крутого есть в других языках. Фреймворк Spring в Java в этом плане очень мощно развит.
Так выглядит обработчик http-запросов:
в Java
Примерно так можно бы сделать в C++, когда доработают поддержку пользовательских атрибутов:
в C++
В C++ типы всех значений вычисляются в процессе компиляции и жестко фиксированы. "Тип"
auto
это просто синтаксический сахар, все равно это будет какой-то реальный фиксированный тип.Все переменные/объекты занимают какое-то количество байт на стеке, и это количество нужно знать заранее, иначе, например, непонятно как вычислить размер stack frame у функции (ассемблеру нужно это знать).
Вот такого в C++ не будет скорее всего никогда:
Аналог того, что происходит в C#/Java, на C++ выглядит скорее как использование std::any, который аллоцирует нужное количество байт для объекта в куче (в отличие от стека, там необязательно знать объем выделяемой памяти в compile-time). Можно иметь один из типов в рантайме:
Ради справедливости, высокочастотный трейдинг это не совсем "типичная" C++ программа.
Если, например, писать реалтаймовую программу по обработке аудио-сигналов (где тоже своя атмосфера), то мы связываем себе руки в направлении:
не блокировать поток (не пытаться завладеть мьютексом, память аллоцировать строго на стеке, не делать I/O - в общем, не делать системных вызовов)
не пользоваться алгоритмами сложности >O(1) / амортизированной сложности
по возможности использовать статический полиморфизм вместо динамического
Поэтому не стоит сравнивать какие-то гиперболизированные свойства.
То, что сортировка станет вдвое быстрее для 99.9% остальных программ - это же круто? В больших корпорациях ускорение на 2-3% это огромные деньги.
Пиши в хидерах код а-ля
using namespace std;
- коллеги скажут спасибо, за то что им не придется это писать в каждом .cpp!Подключай как можно больше хидеров, чтобы каждый .cpp файл раскрывался в 1mln строк - коллеги скажут спасибо за то, что у них больше времени на перекур во время пересборки!
Функция должна вернуть больше чем одно значение? Есть крутой лайфхак - записывай результаты в указатель! Для трёх значений это
int process(int arg, int* res2, int* res3)
.У меня возник похожий вопрос - а сами студенты перед поступлением в распоряжение к топикстартеру в курсе о гарантированном no hire в Huawei/Intel/Nvidia/etc.?
Потому что в свое время я начал было проходить отбор к топикстартеру, так как в пределах факультета кафедра разрекламирована, но остановился на полпути. Про "договоренности" узнал из статьи.
Откуда такой миф, что заниматься "наукой" это нереально здорово, почти как быть сверхчеловеком?
Давайте представим - вы прямо сегодня изобрели лекарство от рака (или что-то подобное, иначе это не "наука", а просиживание штанов) и опубликовались в скопусе.
Вы теперь миллиардер? Нет, все сливки снимет братва с фармкомпаний и академическая мафия, а ты как ехал на маршрутке, так и будешь ехать дальше, ведь у тебя !ПРИЗВАНИЕ! работать за 14-20к.
Про студентов: а кто постановил, что они обязаны работать в науке, особенно под вами? От школьников в 10-11 классах ведь не ждут, что они будут вести уроки за учителей. Так и студенты - они идут в вуз ввиду отсутствия альтернатив (у 95% элементарно откосить от армии), а там у какой-то деловой колбасы на них "виды" в своих корыстных целях. Учитесь работать в рыночной экономике.
С уважением, ваш Фрай
У нас некоторые преподы сходили с ума и присылали какой-то бред
Правила сдачи одного из экзаменов
Скрипт хороший. Жаль только, что многие преподаватели (в основном еще видевшие живого Ленина) ОЧЕНЬ волнуются, если кто-то не слушает именно их пересказ учебника в 8:45, поэтому любят просить включать камеры, задавать рандомные вопросы рандомным людям в рандомное время, и так далее.
Было бы неплохо "из коробки" иметь возможность часть нового кода писать на Rust и связывать его с плюсами. C++ может использовать C, в котором другая система линковки, через
extern "C"
. Почему бы не поддержать в компиляторахextern "Rust"
? Это дало бы буст к юзабельности Rust в реальных проектах и все вышеназванные проекты можно было бы перевезти постепенно.В той же паре Java/Kotlin можно совершенно бесшовно вызывать код одного языка из другого языка.
Вы имеете в виду
String
и&str
? Это практически аналогиstd::string
иstd::string_view
соответственно из плюсов, с такими же сферами применения. У этих двух типов сферы использования пересекаются, но есть случаи когда конкретный тип нужнее. В C++ и в Rust оба типа используются постоянно.Извините, но вы оба считаете что-то не то...
Это первый вариант (оптимизированный):
Это второй вариант (оптимизированный):
Вызов
resize
не влияет совсем, так как размер вектора уже достаточный. Но во втором коде лишняя аллокация и деаллокация памяти, из-за чего второй вариант "типа" медленнее. Я поменял одну строку, результат эквивалентный: https://quick-bench.com/q/fSU3z97n18YhNGBgHmojrtW0Y0U