Чому я більше не використовую сучасний C++

Сучасний C++: що це і як він з'явився?
Протягом останнього десятиліття з приходом стандарту C++11, а перед цим — випереджають його специфікації TR1 і бібліотеки Boost, — в співтоваристві C++-розробників спостерігався масовий перехід на новий стиль програмування, так званий сучасний C++. Цей перехід мав на увазі введення в обіг таких прийомів як ключове слово auto, замикання (лямбда-вирази), варіативні шаблони і багато іншого. C++ виявився благодатним грунтом для експериментів, і на світ з'явилося кілька бібліотек, написаних у новому стилі. Ті, хто зміг розібратися в нових ідіомах начебто SFINAE, диспетчеризації тегів, CRTP, генератора типів, безпечного bool і т. д., або хоча б навчився їх відтворювати, були нагороджені званням гуру.

З появою на початку 1970 -х рр… интуиционистской теорії типів Мартін-Лефа, яка являє собою результат схрещування чистої математики та інформатики, почався період активних досліджень в області мов нового типу, таких як Agda і Epigram. Так був закладений фундамент парадигми функціонального програмування. Всі ці теорії зараз викладаються у вузах і проголошуються в якості «прориву», а в їх розвиток і просування вкладаються величезні кошти. З'явилося навіть ціле співтовариство ораторів, які заробляють на життя пропагандою цього «прориву» серед представників ділової Америки. Тому не дивно, що на поточні рішення Комітету по стандартизації C++ активно впливають нові члени — вчорашні студенти, чия думка була сформована під впливом цього оточення.

Переорієнтація з продуктивності на функціональність
З часом C++ перетворився з «швидкого» мови «функціональний», і про продуктивності забули. Зараз вже ні для кого не секрет, що деякі компоненти C++, наприклад, бібліотека iostream та рядки, в силу своєї природи не можуть працювати швидко; крім того, відсутні деякі основні можливості начебто управління передачею даних по мережі і зовсім вже базові функції, наприклад, найпростіша процедура розбиття рядків. Якщо запитати будь-якого члена Комітету, чому ці недоліки так і не усунули за минулі майже двадцять років, відповідь незмінно буде один і той ж: бо ніхто не хотів возитися з підготовкою відповідної доповіді або пропозиції.

Комітет розраховує використовувати дослідницьку групу SG14 — підрозділ Робочої Групи ISO 21 (WG21), присвячене розробці ігор і високочастотній трейдингу (HFT) — в якості платформи для обговорення подальших поліпшень мови між фахівцями з індустрії з низькими затримками. Однак, судячи з вже відбулися обговорення в дискусійних групах і Стандартом Майкла Уонга (його зміст таке ж веселе, як і назва), ніхто не горить бажанням проводити радикальні реформи, які так необхідні C++, щоб успішно конкурувати в цій області з «C++ з класами».

А чому це, власне, проблема?
Я проводжу експертний аналіз C++-коду для великої кількості компаній-розробників в якості консультанта як зі стратегічних інвестицій, так і з питань оптимізації та збільшення продуктивності додатків, і на власному досвіді переконався, що продуктивність програм, написаних на сучасному C++, залишає бажати кращого. Причина не в тому, що новий стиль не дозволяє створювати високопродуктивні системи з низькими затримками, просто в процесі розробки виникає безліч перешкод, які паралізують роботу програмістів або породжують надзвичайно труднооптимизируемые графи, створюють складності компиляторам. Я невимовно радий, що є Чендлер Карут з його серією відеолекцій, завдяки яким ми можемо відновити втрачений зв'язок (а заодно і дещицю здорового глузду) між мовою C++ і реальністю.

Втрата продуктивності
Перший камінь спотикання, як уже говорилося, — це потенційна втрата продуктивності через більш складного пристрою структур проміжного представлення коду і проходів компілятора. З цієї точки зору Fortran набагато краще, оскільки він простіший і компілятори можуть набагато ефективніше оптимізувати його порівняно з аналогічним кодом на C/C++. Мій власний досвід роботи у сфері HFT та розробці ігор протягом багатьох десятиліть, а також дані авторитетних фахових видань, та й взагалі спостереження будь-якого, хто трохи розбирається в оптимізацію компілятора, показують, що поширене переконання, ніби звичайні та варіативні шаблони дозволяють отримувати на виході набагато більш швидкий асемблерний код завдяки автоматичному «розчинення» C++ коду на етапі компіляції, не підтверджується на практиці. Це не більш ніж омана, при цьому досить стійкий. Фактично має місце зворотне: невеликі фрагменти коду набагато краще компілюються, налагоджують і оптимізуються, коли працюєш зі згенерованим ассемблерным кодом, а не з шаблонами.

Час компіляції
Наступна проблема пов'язана з часом компіляції. Звичайні та варіативні шаблони «славляться» своєю здатністю збільшувати час компіляції в десятки разів через перезбирання набагато більшої кількості залучених в процес файлів у порівнянні з традиційним стилем. У той час як простий, традиційний клас C++ перекомпилируется тільки в тому випадку, якщо були змінені безпосередньо включаються їм розробницькі файли glx, в сучасному C++ одну невелику зміну часто тягне за собою повну перезбирання проекту, на що нерідко йде до десяти хвилин. Для класичного C++ це час, при такій невеликій правці, становить кілька секунд.

Як скоро програміст зможе приступити до тестування згенерованого асемблерного коду, закінчивши вносити необхідні поправки в програму, безпосередньо залежить від якості генерованого коду. Якщо додаток можна швидко зібрати і перевірити, то всі проблемні місця будуть поправлені з більшою ймовірністю. А якщо на компіляцію йде десять хвилин, то ця ймовірність сильно знижується.

Сопровождаемость
Третє, і останнє, перешкода пов'язано зі складністю коду. Як одного разу сказав Эдсгер Дейкстра,

Простота — запорука надійності.

Якщо для того щоб розібратися в коді, доводиться наймати гуру програмування, то або щось не так з кодом, або вибрана мова не підходить для вирішуваних завдань.

Якщо уважно прочитати, мабуть, найвідомішу статтю Дейкстри, «Про шкоду оператора goto», неважко помітити, що головні її положення поширюються і на шаблони (звичайні та варіативні): справа не в тому, що поганий сам механізм, а в тому, що споконвічно властива йому структура неминуче породжує складний код, що кінець кінцем нівелює саме головне достоїнство якісного коду — його зрозумілість.

При створенні торгових систем, коли пересилається по мережі до 100 000 заявок в секунду, а торгові стратегії розробляються і реалізуються кожні два дні, простота коду не просто бажана — вона необхідна. Звідси моє «правило однієї хвилини» при розробці подібних систем:

Якщо за одну хвилину можна зрозуміти, що робить даний C++-файл, вважайте, що код невірний.

Справжня причина
Однак справжня причина, по якій я майже перестав мати справу з сучасним C++, незважаючи на те що вельми досяг успіху в ньому, полягає в тому, що в IT-індустрії з'являється все більше розробок, якими справді варто приділяти увагу.

C++ став схожий на Fortran: він досяг своїх меж. Зараз вже існують настільки швидкі інтерфейси, що саме поняття «тактовий цикл» стає неактуальним для певних вузлів системи. Швидкості досягли таких значень, що два біта інформації, надіслані одночасно по парі суміжних проводів, напевно рассинхронизируются, не пройшовши і метра.

C++ вже не годиться для управління такими швидкостями, які реалізуються в сучасних процесорах, масово випускаються на ринок, оскільки він з самого початку орієнтований на послідовний спосіб передачі даних — навіть в максимально розпаралелених системах на кшталт GPU.

Сучасний розробник, якщо він дійсно хоче йти в ногу з часом, змушений звертатися до нових мов — Verilog та VHDL; він повинен уміти проектувати власні процесори і віртуальні моделі материнських плат, інакше він не впорається з лавиною технологічних досягнень найближчих років. І справа не в тому, що ППВМ (Програмується користувачем вентильна матриця, Field-Programmable Gate Array, FPGA) відрізняються надвисокими швидкостями — це зовсім не так. Насправді вони на порядок повільніше, ніж топові процесори.

Просто зараз з'являється все більше різноманітних реконфігурованих обчислювальних систем. Наприклад, Intel поставляє процесори Xeon з вбудованими ППВМ, а «Інтернет речей» (Internet of Things, IOT) у найближчі п'ять років перетвориться на ринок з оборотом в мільярди доларів, і двигуном цього процесу в значній мірі виступають маленькі десятидоларові ППВМ, для програмування яких доведеться наймати цілу армію кваліфікованих технологів. І повірте мені, програмувати на рівні RTL (register transfer level, рівень реєстрових передач ) в сотні разів складніше, ніж писати код на C++. І якщо вивчення C++ дається нелегко, уявіть, як освоювати ППВМ-програмування на професійному рівні (документація до одного лише інструменту Transceiver Toolkit від Altera займає 700 сторінок, до середовища розробки Quartus — ще 1000, і це не кажучи вже про продукцію Xilinx).

І все ж воно того варто. Коли ви, нарешті, опануєте цими новими мовами і прийомами, перед вами відкриються найбільші можливості для втілення власних ідей. Саме так і народжуються «єдинороги» (стартапи, чия оціночна вартість за короткий термін зростає до мільярда доларів і вище — прим. перекл.) — завдяки людям, які здатні побачити всю картину цілком.

Висновок
Як би там не було, я вважаю, що мова C++ поступово йде в минуле. Як і у випадку з Fortran, його вік дає про себе знати. А тому вкладати сили і час у вдосконалення своїх навичок програмування на сучасному C++ — все одно що вкладатися в Cobol або той же Fortran. Програміст нового часу повинен освоювати нові інструменти, щоб мати можливість управлятися з передовими технологіями, які з'являться в найближчі десятиліття. А часу на вивчення всього цього надто мало.

Примітка перекладача
Я не в усьому згоден з думкою автора, однак, вважаю, що С++ програмістам слід ознайомитися з цією статтею. У мене теж є відчуття, що з сучасним C++, що щось не в порядку. «Наворочений» код на шаблонах стає вкрай складно розуміти і того ж, він не дає обіцяної ефективності. Я взагалі все більше схиляюся в бік написання коду в стилі C++ з класами.

Ах, так, трохи не забув. Використовуйте статичні аналізатори коду, щоб зменшити хоча б кількість дурних помилок — і без них головного болю з C++ вистачає.
Джерело: Хабрахабр

0 коментарів

Тільки зареєстровані та авторизовані користувачі можуть залишати коментарі.