Для меня это была первая поездка за границу на конференцию и первая поездка на конференцию по C++ в качестве докладчика. Я была так взволнована! Я благодарен организаторам, моему работодателю и, конечно, моей семье за то, что это произошло.
Мое волнение было в основном положительным, хотя при нынешнем состоянии авиаперевозок в Европе я также немного беспокоился о том, смогу ли я добраться туда, и смогут ли все добраться туда. В конце концов, все получилось лучше, чем я ожидал!
Конференция проходила в Фолкстоне, Великобритания. Прямо на побережье, где поезд Eurostar выходит из туннеля. В зале было несколько балконов, и когда погода была хорошей (почти все время), можно было даже увидеть северное побережье Франции.
Фолкстон — это именно то, как я представляю себе типичный английский город в сельской местности с его архитектурой и слишком добрыми людьми, которые приветствуют друг друга на улицах. В таком месте так легко почувствовать себя как дома.
Помимо типичной архитектуры, часть Фолкстона представляет собой более буржуазный район. Кажется, что сюда приезжают богатые люди, которые хотят провести время на берегу моря.
На этот раз это были разработчики C++.
Я несколько раз упоминал в своем блоге, что по сути я интроверт, и обсуждение с людьми часто дается мне с трудом. Я часто стараюсь избегать этого. Однако в этот раз я совсем не чувствовал себя таким. Мне нравилось подходить к людям, разговаривать с ними, а также получать удовольствие от того, что ко мне обращаются. Как оратор, это, очевидно, происходило чаще, чем в другое время.
Я не уверен, почему в этот раз я чувствовал себя лучше. Может быть, из-за прошедших COVIDious лет? Может быть, потому что я знал многих из этих людей по Твиттеру, онлайн-пространствам и конференциям, и это дало мне толчок? Кто знает…
Кстати, о толчке. Я остановился в гостинице прямо напротив места проведения конференции вместе с несколькими другими спикерами. Когда в первое утро я спустился позавтракать, меня посадили не одного, а официант предоставил мне место за столом с кучей других спикеров, которых я не знал или, по крайней мере, не знал в лицо. Социализация началась довольно рано.
И несмотря на то, что я интроверт, я стараюсь ухватиться за каждую возможность выйти на сцену и выступить, чтобы попрактиковаться и стать лучше. Для меня не было ничего сложного в том, чтобы выступить с докладом. Из-за недавней очень раздражающей ошибки у меня под рукой была тема. Для меня было большой честью выйти на главную сцену в Фолкстоне и выступить перед таким количеством умных людей.
Во второй вечер у нас был ужин для докладчиков с прекрасным видом на море и вкусной едой.
Из-за дискуссий за столами в зале стало довольно шумно, поэтому многие из нас продолжали делиться историями на террасе. Я знаю, что позже многие продолжили в пабах, но я хотел лечь спать пораньше, потому что на следующее утро у меня был первый слот.
Я говорил о сильно набранных контейнерах и на этот раз остался доволен своим выступлением. Наверное, впервые с тех пор, как я начал выступать на конференциях. Я получил несколько приятных отзывов и очень важное замечание о наследуемых операторах сравнения, так что я тоже кое-чему научился. Подробности смотрите на слайде 33 здесь!
Теперь давайте поговорим о других докладах!
- Три доклада, которые мне особенно понравились
- Что вы подразумеваете под «дружественным к кэшу»? Бьёрн Фахлер
- Шесть способов реализации max: прогулка по дизайну API, висячим ссылкам и ограничениям C++20 от Амира Кирша
- Midnote: For the Sake of Complexity (Ради сложности) Кевлин Хенни
- Три интересные идеи
- Наличие более длинных функций иногда является правильным
- Не всегда передавайте входные аргументы по ссылке const
- Синглтон — это не шаблон проектирования
- Идеи для улучшения
- Заключение
- Подключайтесь глубже
Три доклада, которые мне особенно понравились
Позвольте мне поделиться с вами тремя докладами, которые мне особенно понравились во время мероприятия. Как только записи будут опубликованы на Youtube, я обновлю статью ссылками.
Что вы подразумеваете под «дружественным к кэшу»? Бьёрн Фахлер
Мы часто слышим о хитах и промахах кэша, когда говорим о производительном коде и коде, оптимизированном для производительности (C++). Я так мало знаю об этой теме, что мне непременно захотелось посетить этот доклад. Кроме того, я познакомился с Бьорном во время завтрака после прибытия, и он показался мне очень приятным человеком, который умеет хорошо объяснять.
Я не был разочарован. Он начал с личной истории. Он ожидал, что его код будет ограничен задержкой, но оказалось, что дело в процессоре. Его код проводил большую часть времени в определенной функции schedule_timer
.
Очень скоро он начал говорить об объектах против размеров кэша. Почему и как мы должны ограничивать размеры наших объектов, если у нас их великое множество. Как сказал докладчик, «делать больше работы может быть быстрее, чем делать меньше».
Почему это так?
Погоня за указателями почти всегда приводит к промахам в кэше. Хранение объектов в смежной области памяти и перебор большего количества объектов, чтобы найти что-то, может быть быстрее, чем просто следование указателям.
Эта концепция была доказана в примерах, где Бьорн оптимизировал свой первоначальный код и попробовал использовать множество различных структур данных и модифицированных объектов.
Важным и не очень удивительным выводом является то, что наши прогнозы не всегда верны. Если мы серьезно заботимся о производительности, мы должны постоянно измерять, измерять и измерять.
Шесть способов реализации max: прогулка по дизайну API, висячим ссылкам и ограничениям C++20 от Амира Кирша
Мне кажется забавным, что кто-то постоянно говорит о том, что std::max
сломан. В прошлом году это был Walter E Brown, который говорил о том, что его реализация сломана, поскольку std::min
и std::max
могут возвращать одинаковые значения.
Амир говорил не о проблеме реализации, а скорее о проблеме проектирования. Мы не можем найти максимум для разных типов. Например, std::max(5, 6.5)
не скомпилируется, потому что 5 — это int
, а 6.5 — это double. Конечно, вы можете заставить его компилироваться с помощью static_cast
, но это может показаться некрасивым.
Докладчик показал реализацию для max
, которая может просто взять любые два сравниваемых типа и вернуть максимальное из них, учитывая, были ли они переданы по значению или по ссылке.
Почему я упоминаю этот доклад среди лучших?
Во-первых, это было действительно интересно. Но больше всего мне понравилось то, с какой легкостью Амир стоял на сцене и выполнял живое упражнение по кодированию. Конечно, были некоторые проблемы, не все получалось с первого раза, но он хорошо справился с этими ситуациями. Кроме того, он сделал сессию очень интерактивной, было много вопросов к аудитории, и он часто двигался вперед, основываясь на ответах. Браво!
Midnote: For the Sake of Complexity (Ради сложности) Кевлин Хенни
Присутствие Кевлина на сцене, его улыбка и энтузиазм, с которым он говорит, делают очень трудным не упомянуть его выступления в любое время, когда вы думаете о том, что вам больше всего понравилось.
Я впервые слышал/видел его вживую, и это действительно был сильный опыт.
Но о чем он говорил?
О сложности!
Он показал изображение великолепных швейцарских часов. Это самые сложные часы из когда-либо созданных. И это увеличивает их стоимость!
Теперь представьте, что вы пишете слишком сложную и эгоистичную часть программного обеспечения.
Попробуйте похвастаться его сложностью!
Хотя «разработчиков тянет к сложности, как мотыльков к огню» (Нил Форд), наша работа заключается скорее в том, чтобы максимально упростить программное обеспечение. Нам приходится разбивать большую сложную проблему на маленькие простые вопросы, которые мы можем решить.
Мы склонны обобщать решения там, где обобщение не требуется. «О, я просто добавлю шаблон стратегии здесь, немного стирания типов там, и тогда это будет работать с требованиями следующего года». Проблема в том, что никто об этом не спрашивает, а чаще всего и никто не будет использовать или фактически понимать код. Мы должны заботиться об общих вопросах только тогда, когда это необходимо, в противном случае стремитесь к простоте!
Сначала давайте построим что-то законченное, но простое.
Затем добавим умные части.
Использовать, прежде чем повторно использовать.
Три интересные идеи
Как я обычно делаю с отчетами о поездках, я хочу не только поделиться некоторыми своими мыслями о целых докладах, но иногда я просто хочу передать некоторые идеи, которые показались мне особенно интересными.
Наличие более длинных функций иногда является правильным
На моем бейдже была цитата:
«Ваша функция длиннее 10 строк? Извлекайте до тех пор, пока не упадете».
Я не верю в крайности. Нет ничего черного и белого. Хотя я верю, что в большинстве ситуаций следовать строгим правилам лучше, чем не следовать никаким правилам вообще. Но это все равно не делает их верными в любой ситуации.
Эта цитата, которая также находится в подписи моей корпоративной электронной почты, вызвала много интересных дискуссий. Вы не можете вызвать дискуссию, сказав, что да, иногда вам следует держать свои функции относительно небольшими…
Эту же мысль высказал Арне Мерц в своем докладе «Выявление распространенных запахов кода». Более короткие функции обычно предпочтительнее. Но не всегда.
Но давайте сделаем небольшой шаг назад.
Является ли длинная функция проблемой?
Нет. Это просто запах кода. Как сказал Мартин Фолвер, запах кода — это «поверхностный признак», который обычно соответствует «более глубокой проблеме» в системе.
В данном случае более глубокой проблемой является нарушение принципа единой ответственности.
Но, как обычно подразумевается под этим словом, это не всегда проблема.
В любом случае, невозможно назвать число для максимальной длины функции. Это 100 строк? 20? 10? Сто кажется слишком большим числом, но как насчет 10? Иногда даже это будет слишком долго, но иногда 20 вполне приемлемо.
Часто есть некоторые индикаторы, которые подсказывают факторизацию функции, например, комментарии блоков кода.
// Create the left paddle
sf::RectangleShape leftPaddle;
leftPaddle.setSize(paddleSize - sf::Vector2f(3, 3));
leftPaddle.setOutlineThickness(3);
leftPaddle.setOutlineColor(sf::Color::Black);
leftPaddle.setFillColor(sf::Color(100, 100, 200));
leftPaddle.setOrigin(paddleSize / 2.f);
// Create the right paddle
sf::RectangleShape rightPaddle;
rightPaddle.setSize(paddleSize - sf::Vector2f(3, 3));
rightPaddle.setOutlineThickness(3);
rightPaddle.setOutlineColor(sf::Color::Black);
rightPaddle.setFillColor(sf::Color(200, 100, 100));
rightPaddle.setOrigin(paddleSize / 2.f);
// Create the ball
sf::CircleShape ball;
ball.setRadius(ballRadius - 3);
ball.setOutlineThickness(2);
ball.setOutlineColor(sf::Color::Black);
ball.setFillColor(sf::Color::White);
ball.setOrigin({ballRadius / 2.f, ballRadius / 2.f});
В данном случае очевидно, что мы должны извлечь функции для создания лопастей и мяча. Но представьте себе алгоритм, например, «Решето Эратосфена». Он будет длиннее 10 строк.
Является ли это проблемой?
Нет. Проблема в том, чтобы разбить эту сущность на неполные, бесполезные части только ради того, чтобы сократить ее.
Не следуйте правилам слепо.
Не всегда передавайте входные аргументы по ссылке const
Выступление Виктора Чиуры на конференции C++ MythBuster было очень интересным, и трудно выбрать один миф из его выступления, но вот один.
Мы все узнали, что входные аргументы, не относящиеся к POD, следует передавать через const&
. И я все еще думаю, что это простой способ следовать, простое эмпирическое правило, которое будет достаточно хорошим в большинстве случаев.
В то же время, с появлением семантики перемещения возник новый паттерн. Когда класс получает право собственности на переменную, следует подумать о том, чтобы взять переменную по значению и переместить ее.
class Widget {
std::string id;
std::string name;
public:
Widget(std::string new_id, std::string new_name) : id(std::move(new_id)), name(std::move(new_name)) {
}
};
Некоторым это очень неудобно. Принятие переменной по значению… Можно было бы избежать операции перемещения, если бы существовало две перегрузки: одна для const&
и одна для &&
. Но в подавляющем большинстве случаев это не имеет значения. Одна пощаженная операция перемещения не стоит того, чтобы загрязнять API дополнительной перегрузкой.
Когда класс должен взять на себя право собственности на входные переменные, подумайте о паттерне sink и возьмите их по значению!
Синглтон — это не шаблон проектирования
Клаус Иглебергер, главный организатор Мюнхенской группы пользователей C++, посвятил свое выступление (анти)паттерну Singleton. Но в чем же его проблема? Кроме того, что он представляет собой глобальное состояние…
Проблема возникает из-за плохой классификации, которая также приносит неоправдавшиеся ожидания.
В книге Gang of Four Design Patterns синглтон был перечислен как создающий паттерн проектирования. Его роль заключается в том, чтобы гарантировать создание только одного экземпляра объекта.
Чего мы ожидаем от паттернов проектирования?
В общем, мы ожидаем двух вещей:
- Они должны обеспечивать абстракцию
- Они должны уменьшать количество зависимостей.
Паттерн Singleton не предлагает ничего из этого. Поэтому это не паттерн проектирования, а паттерн реализации.
Это замечание дает возможность комбинировать его с другими техниками и использовать его таким образом, чтобы не усложнять тестирование приложения, а действительно помогать моделировать реальные отношения, не делая программное обеспечение менее тестируемым.
Остальное смотрите в докладе!
Идеи для улучшения
Я постоянно пишу во всех своих отчетах о поездках, что упоминание только хороших сторон было бы очень несбалансированным, и вы, вероятно, подумаете, что я делаю это потому, что мне за это платят. Хотя это правда, что в качестве докладчика большая часть моих расходов была покрыта, я все же считаю, что давать мягкие, конструктивные отзывы полезно и не должно задевать чувства. Итак, позвольте мне упомянуть пару идей.
Первый обед показался немного хаотичным. Как и все остальные, поставщики провизии также страдают от нехватки человеческих ресурсов. В течение следующих двух дней ситуация значительно улучшилась. На третий день они опоздали на несколько минут, что не является проблемой, но я не мог ждать. Мне нужно было сделать длинный телефонный звонок. Я вернулся примерно через 40 минут, и большинство людей закончили пировать, а еды для меня все еще было более чем достаточно. Такого я не ожидал после первого дня, хотел бы я совершенствоваться так же быстро, как адаптировалась служба кейтеринга!
Единственное, что в еде и напитках можно было бы немного улучшить, это ситуация с водой.
Мне понравилось, что повсюду не было воды в бутылках. Лучше избежать всего этого пластика. В то же время нескольких кувшинов воды, даже не во всех перерывах, было явно недостаточно. Возможно, было бы неплохо установить несколько простых, но больших диспенсеров с бутилированной водой, а может быть, просто приклеить несколько табличек с информацией о том, что воду из-под крана можно пить.
И последнее, о чем хотелось бы упомянуть. Спонсоры были великолепны. Помимо финансовой поддержки мероприятия, некоторые из них принесли крутые и полезные сувениры (в частности, Roku и Optiver), и все они были доступны для очень интересных бесед. Единственное, что меня огорчило, это то, как некоторые из них покинули мероприятие. Понятно, если они не могут приехать в последний день, особенно с учетом нынешней ситуации с авиаперевозками, но, вероятно, все они могли бы не разбирать и не собирать свои вещи во время продолжающихся переговоров. Это было немного тревожно. Но в любом случае, большое им спасибо.
Заключение
C++ On Sea была моей первой очной конференцией по C++ в качестве докладчика, и мне она очень понравилась. Несмотря на то, что даже в качестве докладчика и слушателя это было похоже на тяжелую работу и учебу, это было почти как отпуск. Я встретил очень приятных людей, которых знал только онлайн или вообще не знал. Я слушал замечательные доклады и многому научился.
Надеюсь, что этим отчетом о поездке мне удалось вернуть вам что-то из впечатлений, и я надеюсь увидеть вас на одном из будущих мероприятий!
И еще раз большое спасибо всем тем, кто сделал это событие реальностью!
Подключайтесь глубже
Если вам понравилась эта статья, пожалуйста
- нажмите на кнопку «Мне нравится»,
- подпишитесь на мою рассылку
- и давайте общаться в Twitter!