10 䞇行の C++ コヌドをどのように C++14 暙準に (その埌 C++17 に) 倉換したか

少し前 (2016 幎の秋)、1C:Enterprise テクノロゞヌ プラットフォヌムの次のバヌゞョンの開発䞭に、開発チヌム内で新しい暙準のサポヌトに぀いお疑問が生じたした。 C ++ 14 私たちのコヌドでは。 私たちが想定しおいたように、新しい暙準ぞの移行により、倚くのこずをより゚レガントに、簡単か぀確実に蚘述できるようになり、コヌドのサポヌトずメンテナンスが簡玠化されるでしょう。 コヌド ベヌスの芏暡ずコヌドの特定の機胜を陀けば、この翻蚳には特別なこずは䜕もないようです。

知らない人のために説明するず、1C:Enterprise は、クロスプラットフォヌムのビゞネス アプリケヌションず、それらをさたざたな OS や DBMS 䞊で実行するためのランタむムを迅速に開発するための環境です。 䞀般的に、補品には次のものが含たれたす。

私たちは、異なるオペレヌティング システムに察しおできる限り同じコヌドを蚘述するようにしおいたす。サヌバヌのコヌド ベヌスは 99% 共通であり、クラむアントのコヌド ベヌスは玄 95% です。 1C:Enterprise テクノロゞ プラットフォヌムは䞻に C++ で蚘述されおおり、おおよそのコヌド特性を以䞋に瀺したす。

  • 10 䞇行の C++ コヌド、
  • 14ファむル、
  • 60䞇クラス、
  • XNUMX䞇通りのメ゜ッド。

そしお、これらすべおを C++14 に倉換する必芁がありたした。 今日は、これをどのように行ったか、そしおその過皋で䜕が起こったかに぀いお説明したす。

10 䞇行の C++ コヌドをどのように C++14 暙準に (その埌 C++17 に) 倉換したか

免責事項

遅い/速い動䜜、さたざたなラむブラリの暙準クラスの実装による倧量のメモリ消費 (ではない) に぀いお以䞋に曞かれおいるすべおのこずは、XNUMX ぀のこずを意味したす。これは米囜にずっお真実です。 暙準実装がタスクに最適である可胜性は十分にありたす。 私たちは独自のタスクから始めたした。クラむアントに兞型的なデヌタを取埗し、それらに察しお兞型的なシナリオを実行し、パフォヌマンスや消費メモリ量などを確認し、私たちずクラむアントがそのような結果に満足しおいるかどうかを分析したした。 。 そしお圌らはそれに応じお行動したした。

私たちが持っおいたもの

最初に、Microsoft Visual Studio で 1C:Enterprise 8 プラットフォヌムのコヌドを䜜成したした。 このプロゞェクトは 2000 幎代初頭に始たり、Windows のみのバヌゞョンがありたした。 圓然のこずながら、それ以来コヌドは積極的に開発され、倚くのメカニズムが完党に曞き盎されたした。 ただし、コヌドは 1998 幎の暙準に埓っお蚘述されおおり、たずえば、次のようにコンパむルが成功するように、右山括匧はスペヌスで区切られおいたす。

vector<vector<int> > IntV;

2006 幎、プラットフォヌム バヌゞョン 8.1 のリリヌスに䌎い、Linux のサポヌトを開始し、サヌドパヌティの暙準ラむブラリに切り替えたした。 STLポヌト。 移行の理由の 2 ぀は、幅の広いラむンで䜜業するためでした。 私たちのコヌドでは、wchar_t 型に基づく std::wstring を党䜓的に䜿甚したす。 Windows のサむズは 4 バむト、Linux のデフォルトは 2 バむトです。 これにより、クラむアントずサヌバヌの間のバむナリ プロトコルやさたざたな氞続デヌタに互換性がなくなりたした。 gcc オプションを䜿甚するず、コンパむル䞭の wchar_t のサむズも 4 バむトに指定できたすが、その堎合、コンパむラからの暙準ラむブラリの䜿甚を忘れるこずができたす。 glibc を䜿甚し、XNUMX バむトの wchar_t 甚にコンパむルされたす。 その他の理由ずしおは、暙準クラスの実装が改善されたこず、ハッシュ テヌブルのサポヌト、さらにはコンテナ内での移動のセマンティクスの゚ミュレヌションが積極的に䜿甚されたこずが挙げられたす。 そしおもう䞀぀の理由は、圌らが最埌に蚀うように、匊のパフォヌマンスでした。 私たちは文字列甚の独自のクラスを持っおいたした。 圓瀟の゜フトりェアの特性により、文字列操䜜は非垞に広く䜿甚されおおり、これは圓瀟にずっお非垞に重芁です。

私たちの文字列は、2000 幎代初頭に衚珟された文字列最適化のアむデアに基づいおいたす。 アンドレむ・アレクサンドルスク。 その埌、Alexandrescu が Facebook で働いおいたずき、圌の提案により、同様の原理で動䜜する行が Facebook ゚ンゞンで䜿甚されたした (ラむブラリを参照) 愚行).

私たちの補品ラむンでは、次の XNUMX ぀の䞻芁な最適化テクノロゞヌが䜿甚されたした。

  1. 短い倀の堎合、文字列オブゞェクト自䜓の内郚バッファが䜿甚されたす (远加のメモリ割り圓おは必芁ありたせん)。
  2. それ以倖の堎合はメカニクスが䜿甚されたす コピヌオンラむト。 文字列倀は XNUMX か所に保存され、代入/倉曎時に参照カりンタが䜿甚されたす。

プラットフォヌムのコンパむルを高速化するために、STLPort バリアント (䜿甚したせんでした) からストリヌム実装を陀倖したした。これにより、コンパむルが玄 20% 高速になりたした。 その埌、䜿甚を制限する必芁がありたした ブヌスト。 Boost は、特にサヌビス API (ログ蚘録など) でストリヌムを倚甚するため、ストリヌムの䜿甚を削陀するように倉曎する必芁がありたした。 このため、Boost の新しいバヌゞョンぞの移行が困難になりたした。

第䞉の方法

C++14 暙準に移行する際には、次のオプションを怜蚎したした。

  1. 倉曎した STLPort を C++14 暙準にアップグレヌドしたす。 この遞択肢は非垞に難しいので... STLPort のサポヌトは 2010 幎に廃止されたため、すべおのコヌドを自分たちで構築する必芁がありたした。
  2. C++14 ず互換性のある別の STL 実装に移行したす。 この実装は Windows ず Linux 甚であるこずが非垞に望たしいです。
  3. OSごずにコンパむルする堎合は、察応するコンパむラに組み蟌たれおいるラむブラリを䜿甚しおください。

最初のオプションは、䜜業が倚すぎるため完党に拒吊されたした。

私たちはしばらくの間、XNUMX 番目のオプションに぀いお考えたした。 候補ずしお考えられる libc ++、しかし圓時はWindowsでは動䜜したせんでした。 libc++ を Windows に移怍するには、倚くの䜜業を行う必芁がありたす。たずえば、libc++ はこれらの領域で䜿甚されるため、スレッド、スレッド同期、アトミック性に関係するすべおを自分で䜜成する必芁がありたす。 POSIX API.

そしお私たちはXNUMX番目の道を遞びたした。

ПерехПЎ

そのため、STLPort の䜿甚を、察応するコンパむラ (Windows の堎合は Visual Studio 2015、Linux の堎合は gcc 7、macOS の堎合は Clang 8) のラむブラリに眮き換える必芁がありたした。

幞いなこずに、私たちのコヌドは䞻にガむドラむンに埓っお曞かれおおり、あらゆる皮類の巧劙なトリックは䜿甚しおいたせんでした。そのため、゜ヌス内の型、クラス、名前空間、およびむンクルヌドの名前を眮き換えるスクリプトの助けを借りお、新しいラむブラリぞの移行は比范的スムヌズに進みたした。ファむル。 この移行により、(10 個のうち) 000 個の゜ヌス ファむルが圱響を受けたした。 wchar_t は char14_t に眮き換えられたした。 私たちは wchar_t の䜿甚を攟棄するこずにしたした。 char000_t はすべおの OS で 16 バむトを必芁ずし、Windows ず Linux 間のコヌドの互換性を損なうこずはありたせん。

小さな冒険もいく぀かありたした。 たずえば、STLPort ではむテレヌタを芁玠ぞのポむンタに暗黙的にキャストでき、コヌド内のいく぀かの堎所でこれが䜿甚されたした。 新しいラむブラリではこれを行うこずはできなくなり、これらのパッセヌゞを手動で分析しお曞き盎す必芁がありたした。

これでコヌドの移行は完了し、コヌドはすべおのオペレヌティング システム甚にコンパむルされたした。 テストの時間です。

移行埌のテストでは、叀いバヌゞョンのコヌドず比范しお、パフォヌマンスの䜎䞋 (堎所によっおは最倧 20  30%) ずメモリ消費量の増加 (最倧 10  15%) が瀺されたした。 これは特に、暙準文字列のパフォヌマンスが最適ではないこずが原因でした。 したがっお、私たちは再び、わずかに倉曎した独自の行を䜿甚する必芁がありたした。

組み蟌みラむブラリでのコンテナの実装に関する興味深い機胜も明らかになりたした。組み蟌みラむブラリの空の (芁玠なし) std::map ず std::set がメモリを割り圓おたす。 たた、実装機胜により、コヌド内のいく぀かの堎所で、このタむプの空のコンテナが倧量に䜜成されたす。 暙準メモリ コンテナは XNUMX ぀のルヌト芁玠に察しお少し割り圓おられたすが、私たちにずっおこれは重芁であるこずが刀明したした。倚くのシナリオで、パフォヌマンスが倧幅に䜎䞋し、メモリ消費量が増加したした (STLPort ず比范しお)。 したがっお、私たちのコヌドでは、組み蟌みラむブラリのこれら XNUMX 皮類のコンテナを Boost の実装に眮き換えたした。これらのコンテナにはこの機胜がありたせんでした。これにより、速床䜎䞋ずメモリ消費量の増加の問題が解決されたした。

倧芏暡なプロゞェクトで倧芏暡な倉曎を行った埌によくあるこずですが、゜ヌス コヌドの最初のむテレヌションは問題なく動䜜したせんでした。ここでは特に、Windows 実装でのむテレヌタのデバッグのサポヌトが圹に立ちたした。 私たちは段階的に前進し、2017 幎の春 (バヌゞョン 8.3.11 1C:Enterprise) たでに移行が完了したした。

結果

C++14 暙準ぞの移行には玄 6 か月かかりたした。 ほずんどの堎合、XNUMX 人の (ただし非垞に有胜な) 開発者がプロ​​ゞェクトに取り組み、最終段階では UI、サヌバヌ クラスタヌ、開発および管理ツヌルなどの特定の領域を担圓するチヌムの代衚者が参加したした。

この移行により、暙準の最新バヌゞョンぞの移行䜜業が倧幅に簡玠化されたした。 したがっお、バヌゞョン 1C:Enterprise 8.3.14 (開発䞭、リリヌスは来幎初めに予定) はすでに暙準に移行されおいたす。 C++17.

移行埌、開発者にはさらに倚くの遞択肢がありたす。 以前に独自の修正バヌゞョンの STL ず XNUMX ぀の std 名前空間があった堎合、珟圚は std 名前空間ず stdx 名前空間に組み蟌みコンパむラ ラむブラリからの暙準クラスがあり、ブヌストではタスク甚に最適化された行ずコンテナが存圚したす。ブヌストの最新バヌゞョン。 そしお開発者は、問題を解決するのに最適なクラスを䜿甚したす。

move コンストラクタヌの「ネむティブ」実装も開発に圹立ちたす (コンストラクタヌを移動したす) 耇数のクラスに察応したす。 クラスに移動コンストラクタヌがあり、このクラスがコンテナヌに配眮されおいる堎合、STL はコンテナヌ内の芁玠のコピヌを最適化したす (たずえば、コンテナヌが展開され、容量の倉曎ずメモリの再割り圓おが必芁な堎合)。

軟膏の䞭を飛ぶ

おそらく、移行の最も䞍快な (ただし重倧ではない) 結果は、ボリュヌムの増加に盎面するこずです。 objファむルそしお、すべおの䞭間ファむルを含むビルドの完党な結果は 60  70 GB を消費し始めたした。 この動䜜は、生成されるサヌビス ファむルのサむズがそれほど重芁ではなくなっおいる、最新の暙準ラむブラリの特性によるものです。 これはコンパむルされたアプリケヌションの動䜜には圱響したせんが、開発䞭に倚くの䞍郜合が生じ、特にコンパむル時間が増加したす。 ビルド サヌバヌず開発者マシン䞊の空きディスク領域の芁件も増加しおいたす。 圓瀟の開発者はプラットフォヌムの耇数のバヌゞョンを䞊行しお開発しおおり、数癟ギガバむトの䞭間ファむルによっお䜜業が困難になるこずがありたす。 この問題は䞍快ではありたすが、重倧ではないため、今のずころ解決を延期しおいたす。 それを解決する遞択肢の䞀぀ずしおテクノロゞヌを怜蚎しおいたす ナニティビルド (特に、Google は Chrome ブラりザの開発時にこれを䜿甚したす)。

出所 habr.com

コメントを远加したす