Чи практично відмовитися від STL в розробці C ++? [зачинено]


19

Я знаю, що в деяких сферах (наприклад, ігрової індустрії) STL не рекомендується. Отже, моє запитання: чи справді хороша практика не використовувати STL в деяких випадках? Якщо так, то які найбільші причини не використовувати сучасний STL C ++?



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

Щодо пропускання речей під час налагодження, див., Наприклад: stackoverflow.com/questions/2062881/…
Мартін

Це здається гарним питанням. Можливо, хтось може додати "Чому проект вирішив би не використовувати STL?"
Меттью Джеймса Бріггса

Відповіді:


25
  • Я можу придумати лише одну дійсну причину, і це дуже рідко: важкий реальний час. Багато речей у стандартній бібліотеці виділяють пам'ять всередині, і це недостатньо детерміновано для жорстких додатків у режимі реального часу, тому їх потрібно уникати. Зазвичай ці програми досить прості, хоча для розробки потрібен непропорційний час через дуже суворий огляд та тестування.

  • Я можу подумати про одну недійсну, але дуже поширену причину. Розробники, які не розуміють складності обчислювальної техніки, неправильно використовують STL і звинувачують бібліотеку.

    STL, як правило, швидше під час виконання, ніж будь-які рішення у стилі C із покажчиками зворотного виклику, або рішення, засновані на поліморфізмі, з віртуальними методами ( див. Також основну примітку цієї програми Bjarne Stroustrup ). Однак, коли розробник не розуміє заданих специфікацій складності та зловживає бібліотекою, створюючи щось на зразок векторів векторів деяких складних об'єктів (в С ++ 11, це вже не проблема!), Викликають проблеми з продуктивністю і ніж захищаються з "бачите, вектори досить повільні", це може спричинити уявлення про те, що стандартна бібліотека повільна. І як тільки менеджери отримують таке сприйняття, воно може дуже довго прожити в організації.

  • Очевидно, ви не можете використовувати нічого, що платформа, на яку ви орієнтовані, не підтримує. Однак зараз ми орієнтуємось на чотири найпоширеніші мобільні платформи (Android, iOS, Bada та старі WinCE) та використовуємо стандартну бібліотеку та деякі частини Boost для всіх.

    Більшість стандартних бібліотек Microsoft раніше не підтримувалася Microsoft WinCE (іостри IIRC виходили лише з Visual Studio 2005), але STLport можна було використовувати задовго до цього. І зазвичай ви можете отримати це для компіляції до чого завгодно. Тому я б назвав цю причину також недійсною.

    Крім того, досить тривалий час це не "STL", а стандартна бібліотека ANSI C ++. Це визначається тим самим стандартним документом, який визначає саму мову. Все, що не підтримує, насправді не заслуговує на те, щоб називатися C ++.


6
Перший аргумент (у режимі реального часу) не є специфічним для частин STL бібліотеки стандартів. sprintfчасто також виділяє пам'ять. На платформах реального часу стандартні функції бібліотеки також мають детерміновані обмеження. Це ускладнює реалізацію C ++ у реальному часі: вам доведеться ретельно розробити цілу стандартну бібліотеку C ++, яка є більшою роботою, ніж лише невелика стандартна бібліотека C.
MSalters

@MSalters: Безумовно, багато речей не можна використовувати в режимі реального часу. Навіть деякі мовні функції, такі як винятки, не можуть. Досі C ++ є чудовою мовою для цих систем, оскільки вона може поєднувати продуктивність та точний контроль із сильними захисними засобами (найважливішою особливістю для цього є RAII).
Ян Худек

@JanHudec: Дійсно, тому частини STL потрібні лише для "розміщених" реалізацій C ++.
MSalters

7

Я використовую STL та прискорення вже багато років. Якби я хотів відмовитися від цього і використати свої власні інструменти, мотивація буде такою:

  1. Скорочення часу на компіляцію (75%). Тільки включаючи iostreams, ви можете додати 1 мільйон рядків коду до вашого модуля. Так, попередньо складені заголовки дуже допомагають, але це все ще дуже уповільнює компіляцію у великих проектах. Зрештою, він витрачає багато часу на кожного, хто працює над цим.
  2. Продуктивність. (25%) STL написано, щоб він працював загалом, але ви можете оптимізувати ваші структури так, як вам потрібно. Наприклад, у вас можуть бути структури даних з мільйонами коротких рядків. Можливо, набагато швидше використовувати спеціальний клас рядків на основі принципу boost :: small_vector (невеликий статичний локальний вектор даних, динамічне розподілення лише для більших рядків), такі зміни можуть зробити критичні розділи коду в багато разів швидшими.

1
SSO вже поширений.
Дедуплікатор

для нащадків: SSO -> невелика оптимізація рядків, тобто більшість (усіх?) std :: реалізації рядків зберігають невеликі рядки в стеку і переходять на купу, якщо потрібно
синій

Час компіляції - великий
користувач1754322

4

Є одна важлива причина не використовувати стандартну бібліотеку шаблонів C ++: Одна з ваших цільових платформ не має повністю відповідає її реалізації (або її взагалі немає), і ви знаєте, що вона не отримає її протягом наступних років.


3
Ака "не використовуй його, коли у тебе його немає", що має сенс насправді. :)
Xeo

4
Зважаючи на те, що стандартна бібліотека C ++ 03 розроблена таким чином, щоб вона була реалізована лише з точки зору бібліотеки ANSI C89, чи є якась платформа, де ви не змогли отримати принаймні STLPort ?
Ян Худек

@JanHudec Я вважаю, що є платформи без STL, оскільки у них не вистачає пам'яті, щоб обробити все. Зазвичай їм також не вистачає деяких інших функцій C ++ (наприклад, винятки).
Султан

2
@Sulthan: Щодо мікроконтролерів я щось розумію, але вони зазвичай потрапляють у категорію "жорсткого реального часу". Для всього іншого, це переважно попередження, оскільки STL зазвичай такий же ефективний як для пам'яті, так і для продуктивності, як і ручний код. Багато вкладок може спричинити велику кількість бінарних даних, але цього можна навіть уникнути, якщо ретельно виконати за певної вартості продуктивності (що і рішення, виготовлене вручну). Відсутні винятки - це або попереднє уявлення, або лінь, оскільки потрібно визначити та реалізувати виняток ABI.
Ян Худек

4

Я не знаю про складність (ефективність реалізації), але я широко використовую контейнери та рядки Qt замість std, і вони прекрасно працюють. Я також вважаю, що Qt реалізація наборів і списків простіший у використанні.

Отже, відмовитися від STL може бути практично, якщо ви можете використовувати іншу бібліотеку, яка відповідає вашим потребам.


2
Qt-еквіваленти були створені назад, коли не було реалізацій STL, які були б а) доступними, або б) будь-якими корисними. Це єдина причина, яку вони все ще використовують, нічого проти STL сьогодні.
gbjbaanb

1
@Giorgio: проблема полягає в складних програмах, де ви поєднуєте кілька бібліотек. Контейнери STL, будучи стандартними, утворюють lingua franca . Точніше, це їхні конвенції. Найвідоміший приклад - Boost. Він може працювати на контейнерах STL. він також може працювати над контейнерами Qt, але лише тому, що Qt дотримується конвенцій STL - наприкладQList<T>::iterator
MSalters

3
Я не спростовував це, але бачу одну причину: це не відповідає на питання. Ви сказали, що є речі, які потрібно використовувати замість STL, добре, але це не привід уникати STL. Крім того, будь-яка причина уникати STL, ймовірно, стосується також Qt, MFC та інших подібних бібліотек, або навіть більше.
Ян Худек

3
@NoOne: Ми розуміємо, що ви звикли до верблюда, а не до змії, але це не погіршує останнього. І з трьох імен функцій, які ви критикуєте, перше чудово описує тих, хто має щось спільне з c-рядками, а два інших успадковані від C, не обговорюватимуть їх.
Дедуплікатор

1
@NoOne: Як я вже сказав, я абсолютно розумію, що вам зручніше з CamelCase.
Дедуплікатор

3

Патрік згадав про причину не використовувати всю STL, а саме те, що на вашій платформі немає.

Взагалі я думаю, що питання не має сенсу. Це здебільшого не все або нічого, але це вибір. Ви можете вирішити використовувати контейнери та алгоритми, але вирішите використовувати щось поза Std Lib для рядків та i / o.


3

Це не практично, якщо немає важких причин для цього. Деякі з таких причин, які я можу подумати, включають лише часткову або відсутність реалізації STL (або будь-якої іншої частини стандартної бібліотеки) або обмеження ресурсів (пам'ять, швидкість процесора, зберігання, ...), які вам доведеться обійти прокатка власних інструментів, які дотримуються того, що потрібно зробити.

У ігровій індустрії більшість (навіть меншій чи певною мірою) студії мають свої внутрішні бібліотеки та реалізацію багатьох стандартних бібліотечних частин, які добре підібрані для цільової платформи, а в деяких випадках - цільового engnie або навіть самої гри. Простіше кажучи, при розробці гри для консолей апаратне забезпечення дуже обмежене сьогоднішніми стандартами. Існують тисячі і тисячі ліній ручної роботи збірки. Дуже важливо мінімізувати всі види слідів ресурсів у вашому коді, щоб гра запустилася швидше, що дозволить отримати більше вмісту в ігровому світі (або, наприклад, у великому світі), що, сподіваємось, призведе до кращого продукту.

"Кожна успішна гра починається з розгортання власної реалізації пов'язаного списку."


1
Я б міг уявити, що кожна успішна гра починається з написання коду за допомогою стандартної бібліотеки, а потім лише оптимізації коду після того, як гра буде широко профільована. Оптимізація перед тим, як мати дані профілювання, вказуючи, що потрібно оптимізувати, безглуздо.
Кромулент

Правда. Остання фраза була лише грою на "стародавній" спосіб написання ігор на початку 90-х років, коли C ++ був не таким широко розгорнутим, а збірка + C - це шлях. Можливо, я мав би зробити це більш зрозумілим. Це добре стосується ігрової індустрії на консолях, хоча більшість алгоритмів та структур даних написані за замовчуванням, тому що кожен байт і цикл рахується (так, навіть за рахунок ремонтопридатності / портативності / що завгодно).
zxcdw

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

2
@JanHudec Справа в тому, що реалізаціям (і поведінці теж недоторканою) потрібно дуже підходити під завдання. Ви просто не можете зекономити кілька десятків байтів тут і там (зруйнуючи місце розташування посилань), запустити кілька гілок, щоб перевірити введення даних (помилки гілки та помилки кешу інструкцій) і припустити, що компілятор знає, як векторизувати ваші структури даних оптимально скористатися SIMD (вона не буде, або, принаймні, вам доведеться перевірити правильність того, що вона намагається). Звичайно, написання програмного забезпечення в режимі реального часу на ПК не настільки суворе, ви завжди можете скористатися більш швидким процесором. Не в консолях.
zxcdw
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.