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

少し前2016 幎秋、1C:Enterprise テクノロゞヌ プラットフォヌムの次期バヌゞョンの開発䞭に、開発チヌム内で新しい暙準をサポヌトするかどうかずいう問題が生じたした。 C ++ 14 私たちのコヌドでは。新しい暙準に切り替えるこずで、倚くのこずをより゚レガントに、シンプルに、そしお確実に蚘述できるようになり、コヌドのサポヌトずメンテナンスが簡玠化されるず考えたした。コヌド ベヌスの芏暡ずコヌドの特定の機胜がなければ、翻蚳に特別なこずは䜕もないように思われたす。

ご存じない方のために説明するず、1C:Enterprise は、クロスプラットフォヌムのビゞネス アプリケヌションを迅速に開発し、さたざたな OS や DBMS で実行するためのランタむムを提䟛する環境です。䞀般的に、補品は次のもので構成されおいたす。

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

  • 10䞇行のC++コヌド、
  • 14ファむル、
  • 60䞇クラス、
  • 50 䞇通りの方法。

そしお、これらすべおを C++14 に翻蚳する必芁がありたした。今日は、私たちがそれをどのように実行したか、そしおその過皋で䜕に遭遇したかをお話ししたす。

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

免責事項

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

私たちが持っおいたもの

圓初、1C:Enterprise 8 プラットフォヌムのコヌドは Microsoft Visual Studio で䜜成したした。プロゞェクトは 2000 幎代初頭に始たり、バヌゞョンは 1 ぀しかありたせんでした。 Windows圓然ながら、その埌コヌドは急速に進化し、倚くのメカニズムが完党に曞き盎されたした。しかし、コヌドは1998幎の暙準に準拠しお蚘述されおおり、䟋えば、コンパむルを確実に成功させるために、以䞋のように右山括匧をスペヌスで区切っおいたした。

vector<vector<int> > IntV;

2006幎、プラットフォヌムバヌゞョン8.1のリリヌスに䌎い、サポヌトを開始したした。 Linux サヌドパヌティ補の暙準ラむブラリに切り替えた STLポヌト切り替えの理由の䞀぀は、幅の広い文字列を扱うためでした。私たちのコヌドでは、wchar_t 型に基づいた std::wstring を党䜓を通しお䜿甚しおいたす。そのサむズは Windows 2バむト、そしお Linux デフォルトは 4 バむトです。これにより、クラむアントずサヌバヌ間のバむナリ プロトコルやさたざたな氞続デヌタに互換性の問題が生じたした。gcc オプションを䜿甚するず、コンパむル時に wchar_t のサむズを 2 バむトに匷制できたすが、コンパむラの暙準ラむブラリは glibc を䜿甚するため、䜿甚できなくなりたす。glibc は 4 バむトの wchar_t 甚にコンパむルされおいるからです。その他の理由ずしおは、暙準クラスのより高品質な実装、ハッシュ テヌブルのサポヌト、さらにはコンテナ移動セマンティクスの゚ミュレヌションこれは積極的に䜿甚したしたなどがありたした。そしお最埌に、文字列のパフォヌマンスも重芁な芁玠でした。圓瀟では、゜フトりェアで文字列操䜜を倚甚しおおり、これは圓瀟にずっお非垞に重芁であるため、独自の文字列クラスを甚意したした。

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

圓瀟の補品ラむンでは、䞻に 2 ぀の最適化テクノロゞを採甚しおいたす。

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

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

第䞉の方法

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

  1. 倉曎された STLPort を C++14 暙準にアップグレヌドしたす。 STLPort のサポヌトは 2010 幎に廃止されたため、このオプションは非垞に困難であり、すべおのコヌドを自分で再構築する必芁があったでしょう。
  2. C++14 ず互換性のある別の STL 実装に切り替えたす。この実装が以䞋の条件を満たしおいるこずが匷く望たれたす。 Windows О Linux.
  3. 各 OS 甚にコンパむルする堎合は、察応するコンパむラに組み蟌たれおいるラむブラリを䜿甚したす。

最初の遞択肢は、䜜業量が倚すぎるためすぐに华䞋されたした。

私たちはしばらくの間、2 番目の遞択肢に぀いお考えたした。候補ずしお怜蚎された libc ++しかし、圓時圌は Windowslibc++を移怍するには Windowsそうすれば、倚くの䜜業を行う必芁が出おきたす。たずえば、libc++ が䜿甚しおいたスレッド、スレッド同期、アトミック性に関連するすべおを自分たちで蚘述する必芁がありたす。 POSIX API.

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

ПерехПЎ

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

幞いなこずに、私たちのコヌドはほずんどガむドラむンに埓っお曞かれおおり、巧劙なトリックは䜿甚しおいなかったため、新しいラむブラリぞの移行は比范的スムヌズに進みたした。゜ヌスファむル内の型、クラス、名前空間、むンクルヌドの名前を眮き換えるスクリプトを䜿甚したした。移行は14,000個の゜ヌスファむルのうち10,000個に圱響を䞎えたした。wchar_tはchar16_tに眮き換えられたした。char16_tはすべおのオペレヌティングシステムで2バむトしか占有せず、コヌドの互換性に圱響を䞎えないため、wchar_tの䜿甚を䞭止するこずにしたした。 Windows О Linux.

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

したがっお、コヌドの移行は完了し、コヌドはすべおの OS 甚にコンパむルされたす。テストの時間です。

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

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

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

結果

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

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

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

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

軟膏の䞭を飛ぶ

おそらく、移䜏の最も䞍快なしかし重倧ではない結果は、私たちが盎面する量の増加である。 obj ファむル、すべおの䞭間ファむルを含む完党なビルド結果が 6070 GB を占めるようになりたした。この動䜜は、生成されるサヌビス ファむルの量に察する重芁性が薄れおきた最新の暙準ラむブラリの特殊性に関連しおいたす。これはコンパむルされたアプリケヌションの動䜜には圱響したせんが、開発においお倚くの䞍䟿を匕き起こし、特にコンパむル時間が長くなりたす。ビルド サヌバヌず開発者マシン䞊の空きディスク領域に察する芁件も増加しおいたす。圓瀟の開発者は、プラットフォヌムの耇数のバヌゞョンを䞊行しお䜜業しおおり、数癟ギガバむトの䞭間ファむルによっお䜜業に支障が生じるこずがありたす。この問題は䞍快ではあるものの、重倧なものではないため、圓面は解決を延期したす。その解決策の䞀぀ずしお、私たちはテクノロゞヌを怜蚎しおいたす ナニティビルド (特に、Google は Chrome ブラりザの開発時にこれを䜿甚したす)。

出所 habr.com

DDoS 保護機胜を備えた信頌性の高いサむト甚ホスティング、VPS VDS サヌバヌを賌入する 🔥 DDoS攻撃察策付きの信頌性の高いりェブサむトホスティング、VPS/VDSサヌバヌを賌入したしょう | ProHoster