C ++開発でSTLを放棄するのは実用的ですか?[閉まっている]


19

一部の分野(ゲーム業界など)では、STLはお勧めできません。だから私の質問は次のとおりです:場合によってはSTLを使用しないことは本当に良い習慣ですか?もしそうなら、最新のC ++のSTLを使用しない最大の理由は何ですか?



私の同僚の何人かは、イテレータはデバッグを難しくしていると主張します。なぜなら、ステップインが簡単ではないことがあり、これはラムダにも当てはまるからです。あなたの反応はどうですか?
キャプテンJH

デバッグ中の内容のスキップについては、たとえば、次を参照してください。stackoverflow.com
Martin Ba

これは良い質問のようです。誰かが「なぜプロジェクトがSTLを使用しないことを選択するのか?」
マシュージェームズブリッグス

回答:


25
  • 正当な理由は1つしか考えられませんが、それは非常にまれです:ハードリアルタイム。標準ライブラリの多くの要素は内部的にメモリを割り当てますが、ハードリアルタイムアプリケーションには決定論的ではないため、それらを避ける必要があります。これらのアプリケーションは通常非常に単純ですが、非常に厳密なレビューとテストのために開発に不均衡な時間がかかります。

  • 1つの無効な、しかし非常に一般的な理由を考えることができます:計算の複雑さを理解せず、STLを誤用してライブラリを非難する開発者。

    STLは通常、コールバックポインターを使用したCスタイルソリューションまたは仮想メソッドを使用したポリモーフィズムベースのソリューションよりも実行時に高速です(このBjarne Stroustrupの基調講演も参照してください)。ただし、開発者が与えられた複雑さの仕様を理解せず、いくつかの複雑なオブジェクトのベクトルのベクトルのようなものを作成してライブラリを誤用すると(C ++ 11では問題になりません!)、パフォーマンスの問題を引き起こし、自分自身を守るよりも「おわかりのように、ベクトルはかなり遅い」と、標準ライブラリが遅いという認識を引き起こす可能性があります。そして、マネージャーがそのような認識を得ると、組織内で非常に長く生きることができます。

  • 明らかに、ターゲットとしているプラ​​ットフォームがサポートしていないものは使用できません。ただし、現在最も一般的な4つのモバイルプラットフォーム(Android、iOS、Bada、および古いWinCE)を対象としており、それらすべてで標準ライブラリとBoostの一部を使用しています。

    標準ライブラリの多くは、WinCEの初期段階でMicrosoftによってサポートされていませんでした(IIRC iostreamはVisual Studio 2005でのみ登場しました)が、その前にSTLportを使用することは可能でした。そして、通常は何でもコンパイルすることができます。したがって、この理由も無効だと思います。

    その上、かなり長い間「STL」ではなく、ANSI C ++標準ライブラリです。言語自体を定義する非常に同じ標準文書によって定義されます。それをサポートしていないものは、実際にはC ++と呼ぶに値しません。


6
最初の引数(リアルタイム)は、標準ライブラリのSTL部分に固有ではありません。sprintf多くの場合、メモリも割り当てます。リアルタイムプラットフォームでは、標準ライブラリ関数にも確定的な制限があります。これにより、リアルタイムC ++の実装が難しくなります。C++標準ライブラリ全体を慎重に開発する必要があります。これは、小さなC標準ライブラリよりも多くの作業です。
–MSalters

@MSalters:確かに、リアルタイム要件の下では多くのものを使用できません。例外のような一部の言語機能でもできません。それでも、C ++は、パフォーマンスと正確な制御を強力な保護手段と組み合わせることができるため、これらのシステムに最適な言語です(RAIIはそのための最も重要な機能です)。
Jan Hudec

@JanHudec:実際、STLパーツは「ホストされた」C ++実装にのみ必要です。
-MSalters

7

私はすでにSTLとブーストを長年使用しています。放棄してカスタムツールを使用する場合、その動機は次のようになります。

  1. コンパイル時間の短縮(75%)。iostreamを含めるだけで、モジュールに100万行のコードを追加できます。はい、プリコンパイル済みヘッダーは大いに役立ちますが、それでも大きなプロジェクトではコンパイルがかなり遅くなります。長い目で見れば、誰もがそれに取り組んでいる多くの時間を無駄にします。
  2. パフォーマンス。(25%)STLは一般的に機能するように記述されていますが、構造を最適化して、希望どおりに機能することができます。たとえば、数百万の短い文字列を持つデータ構造があるとします。boost :: small_vector(データの小さな静的ローカルベクトル、大きな文字列のみの動的割り当て)の原則に基づいたカスタム文字列クラスを使用すると、はるかに高速になる可能性があります。

1
SSOはすでに一般的です。
デュプリケータ

後世のために:SSO->小さな文字列の最適化、つまりほとんどの(すべて?)std :: string実装はスタック上に小さな文字列を保持し、必要に応じてヒープに切り替えます

コンパイル時間は大きなものです
user1754322

4

C ++標準テンプレートライブラリを使用しない大きな正当な理由が1つあります。ターゲットプラットフォームの1つに完全に準拠した実装がない(または実装されていない)ため、1つが取得されないことがわかります。数年以内に。


3
別名「持っていないときは使用しないでください」、これは本当に理にかなっています。:)
Xeo

4
C ++ 03標準ライブラリがANSI C89ライブラリのみで実装されるように設計されていることを考えると、少なくともSTLPortを取得できなかったプラットフォームはありますか?
ジャン・ヒューデック

@JanHudecすべてを処理するのに十分なメモリがないため、STLのないプラットフォームがあると思います。通常、他のC ++機能もいくつかあります(例外など)。
スルタン

2
@Sulthan:マイクロコントローラーの場合、私はある程度理解していますが、それらは通常「ハードリアルタイム」カテゴリに分類されます。それ以外の場合、STLは通常、手作りのコードと同じくらいメモリとパフォーマンスの両方で効率的であるため、それはほとんど先入観です。インライン化が多いとバイナリが大きくなる可能性がありますが、パフォーマンスコストを慎重に実装することで回避することもできます(手作りのソリューションにもあります)。また、例外ABIを定義して実装するには手間がかかるため、欠落している例外も先入観または怠lazです。
ジャン・ヒューデック

4

複雑さ(実装の効率)については知りませんが、stdの代わりにQtコンテナと文字列を広範囲に使用していますが、それらは正常に動作します。また、セットとリストのQt実装の方が使いやすいと感じています。

したがって、ニーズに合った別のライブラリを使用できる場合は、STLを放棄することが実用的です。


2
Qtに相当するものは、a)利用可能、またはb)いずれかの良いSTL実装がなかったときに作成されました。それが今でも使われている唯一の理由であり、今日のSTLに反することはありません。
-gbjbaanb

1
@Giorgio:問題は、複数のライブラリを組み合わせる複雑なアプリケーションにあります。標準であるSTLコンテナは、共通語を形成します。より正確には、そうするのは彼らの慣習です。最も有名な例はBoostです。STLコンテナで動作します。Qtコンテナでも機能しますが、これはQtがSTL規則にQList<T>::iterator
準拠し

3
私はそれを支持しませんでしたが、一つの理由がわかります。それは質問に答えないからです。あなたは、STLの代わりに使用するものがあると言っていますが、それはSTLを避ける理由ではありません。STLを回避する理由に加えて、おそらくQt、MFC、およびその他のそのようなライブラリにも同様に、またはそれ以上に適用されます。
ジャン・ヒューデック

3
@NoOne:あなたは、スネークケースではなく、ラクダケースに慣れていることがわかりますが、それは後者を悪化させません。そして、あなたが批判する3つの関数名のうち、1つ目はc文字列と関係がある人にとって完全に記述的であり、他の2つはCから継承されています。
デュプリケータ

1
@NoOne:私が言ったように、私はあなたがCamelCaseに慣れていることを完全に理解しています。
デデュプリケーター

3

Patrickは、STL全体を使用しない理由、つまり、プラットフォームにSTLがないことについて言及しています。

全体として、私は質問の要点が欠けていると思います。ほとんどの場合、すべてか無かの決定ではなく、ピックアンドチョイスの1つです。コンテナとアルゴリズムを使用することを決定するかもしれませんが、文字列とI / OにはStd Lib以外の何かを使用することを決定します。


3

そうする大きな理由がない限り、実用的ではありません。私が考えることができるそのような理由の一部には、STL(または標準ライブラリの他の部分)の実装の一部または欠如のみ、または回避する必要があるリソース制限(メモリ、CPU速度、ストレージなど)が含まれます達成する必要があるものに準拠する独自のツールを展開します。

ゲーム業界では、ほとんどのスタジオ(ある程度小さい場合でも)には、ターゲットプラットフォームや場合によってはターゲットゲームやゲーム自体に合わせて調整された多くの標準ライブラリパーツの内部ライブラリと実装があります。コンソール用のゲームを開発する場合、ハードウェアは今日の標準によって非常に制限されています。数千の手作りのアセンブリのラインが理由であります。コード内のあらゆる種類のリソースフットプリントを最小限に抑えることが非常に重要です。これにより、ゲームがより速く実行され、ゲームの世界(たとえば、より大きな世界)でより多くのコンテンツが可能になり、より良い製品ができます。

「成功するゲームはすべて、独自のリンクリストの実装を展開することから始まります。」


1
成功するゲームはすべて、標準ライブラリを使用してコードを記述し、ゲームが広範囲にプロファイリングされた後にのみコードを最適化することから始まります。最適化が必要なものを示すデータをプロファイリングする前に最適化することは無意味です。
Cromulent

本当です。最後のフレーズは、C ++がそれほど広く展開されておらず、アセンブリ+ Cが進むべき方法だった90年代前半のゲームを書く「古代の」方法の単なる遊びでした。おそらく私はそれをもっと明確にすべきだった。コンソールのゲーム業界によく当てはまりますが、ほとんどのアルゴリズムとデータ構造は、すべてのバイトとサイクルがカウントされるため、デフォルトで手書きになっています(そうです、メンテナンス性/移植性/なんでも犠牲になります)。
zxcdw

2
それは、それが生きている古い経験の多くであると言われるべきです。近代的なオプティマイザーは通常、プログラマーが手作業で行うよりも簡単な保守可能なコードからより良いアセンブリを生成し、STLやBoostなどの汎用テンプレートは、すべてを手作業で特殊なケースと同じくらい効率的なコードにインライン化します。しかし、そうではなかった時代に始まった多くのコードと、当時取引を学んだ多くの人々がいて、もはや意味をなさないとしてもそのように働き続けています。
ジャン・ヒューデック

2
@JanHudec問題は、実装(および動作も事実上)がタスクに合わせて非常に調整する必要があることです。あちこちで数十バイトを無駄にせず(参照の局所性を損なう)、入力を検証するためにいくつかのブランチをドロップし(ブランチの予測ミスと命令キャッシュミス)、コンパイラがデータ構造をベクトル化する方法を知っていると仮定するだけですSIMDを活用するために最適化されます(そうしないか、少なくとも、試行した内容が正しいことを確認する必要があります)。もちろん、PCでリアルタイムソフトウェアを書くことはそれほど厳密ではありません。より高速なCPUをいつでも投入できます。コンソールではありません。
zxcdw
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.