Kepiye cara nerjemahake 10 yuta baris kode C ++ menyang standar C ++ 14 (banjur dadi C ++ 17)

Sawetara wektu kepungkur (ing musim gugur 2016), sajrone pangembangan versi sabanjure 1C: platform teknologi Enterprise, pitakonan muncul ing tim pangembangan babagan ndhukung standar anyar. C ++ 14 ing kode kita. Transisi menyang standar anyar, kaya sing kita anggep, bakal ngidini kita nulis akeh perkara sing luwih elegan, gampang lan andal, lan bakal nyederhanakake dhukungan lan pangopènan kode kasebut. Lan misale jek ora ana sing luar biasa ing terjemahan kasebut, yen ora kanggo ukuran basis kode lan fitur spesifik kode kita.

Kanggo sing ora ngerti, 1C: Enterprise minangka lingkungan kanggo pangembangan cepet aplikasi bisnis lintas platform lan runtime kanggo eksekusi ing macem-macem OS lan DBMS. Umumé, produk kasebut ngemot:

  • Kluster Server Aplikasi, mlaku ing Windows lan Linux
  • Pelanggan, nggarap server liwat http(s) utawa protokol binar dhewe, bisa digunakake ing Windows, Linux, macOS
  • klien web, mlaku ing browser Chrome, Internet Explorer, Microsoft Edge, Firefox, Safari (ditulis nganggo JavaScript)
  • Lingkungan pembangunan (Configurator), dianggo ing Windows, Linux, macOS
  • Piranti administrasi server aplikasi, mbukak ing Windows, Linux, macOS
  • Klien seluler, nyambung menyang server liwat http (s), dianggo ing piranti seluler sing nganggo Android, iOS, Windows
  • Platform seluler - kerangka kanggo nggawe aplikasi seluler offline kanthi kemampuan kanggo nyinkronake, mlaku ing Android, iOS, Windows
  • Lingkungan pangembangan 1C: Piranti Pangembangan Perusahaan, ditulis nganggo aksara Jawa
  • Server Sistem Interaksi

Kita nyoba nulis kode sing padha kanggo sistem operasi sing beda-beda - basis kode server 99% umum, basis kode klien kira-kira 95%. Platform teknologi 1C: Perusahaan utamane ditulis ing C++ lan karakteristik kode kira-kira diwenehi ing ngisor iki:

  • 10 yuta baris kode C++,
  • 14 ewu file,
  • 60 ewu kelas,
  • setengah yuta cara.

Lan kabeh barang iki kudu diterjemahake menyang C++ 14. Dina iki kita bakal pitutur marang kowe carane nindakake iki lan apa kita ketemu ing proses.

Kepiye cara nerjemahake 10 yuta baris kode C ++ menyang standar C ++ 14 (banjur dadi C ++ 17)

Penafian

Kabeh sing ditulis ing ngisor iki babagan karya alon / cepet, (ora) konsumsi memori gedhe dening implementasine kelas standar ing macem-macem perpustakaan tegese siji bab: iki bener FOR US. Bisa uga implementasi standar bakal paling cocog kanggo tugas sampeyan. Kita miwiti saka tugas kita dhewe: kita njupuk data sing khas kanggo klien kita, mbukak skenario khas, ndeleng kinerja, jumlah memori sing dikonsumsi, lan liya-liyane, lan nganalisa apa kita lan klien puas karo asil kasebut utawa ora. . Lan padha tumindak gumantung ing.

Apa kita wis

Kaping pisanan, kita nulis kode kanggo platform 1C: Enterprise 8 ing Microsoft Visual Studio. Proyek kasebut diwiwiti ing awal 2000-an lan kita duwe versi mung Windows. Alami, wiwit kode kasebut aktif dikembangake, akeh mekanisme sing wis ditulis maneh. Nanging kode kasebut ditulis miturut standar 1998, lan, contone, kurung sudut tengen kita dipisahake kanthi spasi supaya kompilasi bisa sukses, kaya mangkene:

vector<vector<int> > IntV;

Ing taun 2006, kanthi rilis platform versi 8.1, kita wiwit ndhukung Linux lan ngalih menyang perpustakaan standar pihak katelu. STLPort. Salah sawijining alasan kanggo transisi yaiku nggarap garis sing amba. Ing kode kita, kita nggunakake std :: wstring, sing adhedhasar jinis wchar_t, ing saindhenging. Ukurane ing Windows yaiku 2 bita, lan ing Linux standar yaiku 4 bita. Iki nyebabake ora kompatibel protokol binar antarane klien lan server, uga macem-macem data sing terus-terusan. Nggunakake opsi gcc, sampeyan bisa nemtokake manawa ukuran wchar_t sajrone kompilasi uga 2 byte, nanging sampeyan bisa lali babagan nggunakake perpustakaan standar saka kompiler, amarga nggunakake glibc, sing dikompilasi kanggo wchar_t 4-bait. Alasan liyane yaiku implementasine kelas standar sing luwih apik, dhukungan kanggo tabel hash, lan malah emulasi semantik obah ing wadhah, sing digunakake kanthi aktif. Lan siji alesan liyane, minangka padha ngomong pungkasan nanging paling ora, kinerja senar. Kita duwe kelas dhewe kanggo strings, amarga ... Amarga spesifik piranti lunak kita, operasi senar digunakake banget lan kanggo kita iki kritis.

String kita adhedhasar gagasan optimasi senar sing ditulis ing awal 2000-an Andrei Alexandrescu. Mengko, nalika Alexandrescu kerja ing Facebook, miturut sarane, baris digunakake ing mesin Facebook sing makarya ing prinsip sing padha (ndeleng perpustakaan kadunungan kawicaksanan).

Baris kita nggunakake rong teknologi optimasi utama:

  1. Kanggo nilai cendhak, buffer internal ing obyek senar dhewe digunakake (ora mbutuhake alokasi memori tambahan).
  2. Kanggo kabeh liyane, mekanika digunakake Salin Ing Tulis. Nilai senar disimpen ing sak panggonan, lan counter referensi digunakake sak assignment / modifikasi.

Kanggo nyepetake kompilasi platform, kita ora kalebu implementasi stream saka varian STLPort (sing ora digunakake), iki menehi kompilasi 20% luwih cepet. Banjur kita kudu nggunakake winates ngedongkrak. Boost nggunakake stream, utamane ing API layanan (contone, kanggo logging), mula kita kudu ngowahi kanggo mbusak panggunaan stream. Iki, banjur, nggawe angel kanggo kita pindhah menyang versi anyar Boost.

cara katelu

Nalika pindhah menyang standar C++ 14, kita nimbang opsi ing ngisor iki:

  1. Nganyarke STLPort sing diowahi dadi standar C ++ 14. Pilihan kasebut angel banget, amarga ... support kanggo STLPort iki mandhek ing 2010, lan kita kudu mbangun kabeh kode dhewe.
  2. Transisi menyang implementasine STL liyane sing kompatibel karo C ++ 14. Apike banget yen implementasine iki kanggo Windows lan Linux.
  3. Nalika ngumpulake kanggo saben OS, nggunakake perpustakaan dibangun menyang compiler cocog.

Opsi pisanan ditolak langsung amarga akeh banget karya.

Kita mikir babagan pilihan kapindho kanggo sawetara wektu; dianggep minangka calon libc++, nanging ing wektu iku ora bisa digunakake ing Windows. Kanggo port libc ++ menyang Windows, sampeyan kudu nindakake akeh pakaryan - contone, nulis kabeh sing ana hubungane karo benang, sinkronisasi benang lan atomicity, amarga libc++ digunakake ing wilayah kasebut. POSIX API.

Lan kita milih cara katelu.

Transisi

Dadi, kita kudu ngganti panggunaan STLPort karo perpustakaan kompiler sing cocog (Visual Studio 2015 kanggo Windows, gcc 7 kanggo Linux, clang 8 kanggo macOS).

Untunge, kode kita ditulis utamane miturut pedoman lan ora nggunakake macem-macem trik sing cerdas, mula migrasi menyang perpustakaan anyar ditindakake kanthi lancar, kanthi bantuan skrip sing ngganti jeneng jinis, kelas, ruang jeneng lan kalebu ing sumber. berkas. Migrasi kena pengaruh 10 file sumber (saka 000). wchar_t diganti karo char14_t; kita mutusaké kanggo nglirwaaken nggunakake wchar_t, amarga char000_t njupuk 16 bita ing kabeh OS lan ora ngrusak kompatibilitas kode antarane Windows lan Linux.

Ana sawetara petualangan cilik. Contone, ing STLPort iterator bisa implicitly matak menyang pointer kanggo unsur, lan ing sawetara panggonan ing kode iki digunakake. Ing perpustakaan anyar ora bisa ditindakake maneh, lan bagean kasebut kudu dianalisis lan ditulis maneh kanthi manual.

Dadi, migrasi kode wis rampung, kode kasebut dikompilasi kanggo kabeh sistem operasi. Wektu kanggo tes.

Tes sawise transisi nuduhake penurunan kinerja (ing sawetara panggonan nganti 20-30%) lan nambah konsumsi memori (nganti 10-15%) dibandhingake karo versi kode lawas. Iki, utamane, amarga kinerja suboptimal saka senar standar. Mulane, kita maneh kudu nggunakake dhewe, rada diowahi baris.

Fitur menarik saka implementasine kontaner ing perpustakaan sing ditempelake uga dicethakaké: kosong (tanpa unsur) std :: map lan std :: nyetel saka perpustakaan dibangun ing allocate memori. Lan amarga fitur implementasine, ing sawetara panggonan ing kode cukup akèh kontaner saka jinis iki digawe. Wadhah memori standar diparengake sethithik, kanggo siji unsur oyod, nanging kanggo kita iki kritis - ing sawetara skenario, kinerja kita mudhun sacara signifikan lan konsumsi memori tambah (dibandhingake karo STLPort). Mulane, ing kode kita ngganti rong jinis wadhah kasebut saka perpustakaan sing dibangun kanthi implementasine saka Boost, ing ngendi wadhah kasebut ora duwe fitur iki, lan iki ngrampungake masalah karo kalem lan konsumsi memori sing tambah.

Kaya sing asring kedadeyan sawise owah-owahan gedhe-gedhe ing proyek gedhe, pengulangan kode sumber pisanan ora bisa ditindakake tanpa masalah, lan ing kene, utamane, dhukungan kanggo iterator debugging ing implementasi Windows kasedhiya. Langkah demi langkah kita maju, lan ing musim semi 2017 (versi 8.3.11 1C:Enterprise) migrasi wis rampung.

Hasil

Transisi kanggo standar C ++ 14 njupuk kita bab 6 sasi. Umume wektu, siji (nanging qualified banget) pangembang makarya ing project, lan ing tataran pungkasan wakil saka tim tanggung jawab kanggo wilayah tartamtu digabung ing - UI, kluster server, pembangunan lan alat administrasi, etc.

Transisi nemen nyederhanakake karya kita babagan migrasi menyang versi standar paling anyar. Mangkono, versi 1C: Enterprise 8.3.14 (ing pembangunan, rilis dijadwal kanggo awal taun ngarep) wis ditransfer menyang standar. C++ 17.

Sawise migrasi, pangembang duwe opsi liyane. Yen sadurunge kita duwe versi modifikasi saka STL lan siji ruang jeneng std, saiki kita duwe kelas standar saka perpustakaan kompiler sing dibangun ing ruang jeneng std, ing ruang jeneng stdx - garis lan wadhah sing dioptimalake kanggo tugas kita, kanthi nambah - versi paling anyar saka ngedongkrak. Lan pangembang nggunakake kelas sing paling cocog kanggo ngrampungake masalahe.

Implementasi "native" saka konstruktor pamindhahan uga mbantu ing pembangunan (mindhah konstruktor) kanggo sawetara kelas. Yen kelas wis konstruktor pamindhahan lan kelas iki diselehake ing wadhah, banjur STL ngoptimalake Nyalin unsur nang wadhah (Contone, nalika wadhah ditambahi lan iku perlu kanggo ngganti kapasitas lan realokasi memori).

Sendok tar

Mbokmenawa akibat sing paling ora nyenengake (nanging ora kritis) saka migrasi yaiku yen kita ngadhepi paningkatan volume. file obj, lan asil lengkap mbangun karo kabeh file penengah wiwit njupuk munggah 60-70 GB. Prilaku iki amarga keanehan perpustakaan standar modern, sing dadi kurang kritis babagan ukuran file layanan sing digawe. Iki ora mengaruhi operasi aplikasi sing dikompilasi, nanging nyebabake sawetara kesulitan ing pangembangan, utamane, nambah wektu kompilasi. Keperluan kanggo ruang disk gratis ing server mbangun lan ing mesin pangembang uga saya tambah. Pangembang kita nggarap sawetara versi platform kanthi podo karo, lan atusan gigabyte file penengah kadhangkala nggawe kesulitan ing karyane. Masalah kasebut ora nyenengake, nanging ora kritis; saiki wis nundha solusi kasebut. Kita nganggep teknologi minangka salah sawijining pilihan kanggo ngrampungake mbangun kesatuan (utamane, Google nggunakake nalika ngembangake browser Chrome).

Source: www.habr.com

Add a comment