Бид 10 сая мөр C++ кодыг C++14 стандарт руу (дараа нь C++17 руу) хэрхэн хөрвүүлсэн бэ?

Хэсэг хугацааны өмнө (2016 оны намар) 1C: Enterprise технологийн платформын дараагийн хувилбарыг боловсруулах явцад шинэ стандартыг дэмжих тухай асуулт хөгжлийн багийн дотор гарч ирэв. C ++ 14 байна Манай кодонд. Бидний таамаглаж байсанчлан шинэ стандартад шилжсэнээр олон зүйлийг илүү дэгжин, энгийн бөгөөд найдвартай бичих боломжийг олгож, кодын дэмжлэг, засвар үйлчилгээг хялбарчлах болно. Мөн кодын баазын цар хүрээ, манай кодын онцлог шинж чанарыг харгалзан үзэхгүй бол орчуулгад ер бусын зүйл байхгүй бололтой.

Мэдэхгүй хүмүүсийн хувьд 1С: Enterprise нь платформ хоорондын бизнесийн хэрэглээний программуудыг хурдацтай хөгжүүлэх орчин бөгөөд тэдгээрийг өөр өөр үйлдлийн систем болон DBMS дээр ажиллуулах хугацаа юм. Ерөнхийдөө бүтээгдэхүүн нь дараахь зүйлийг агуулна.

Бид аль болох өөр өөр үйлдлийн системүүдэд ижил код бичихийг хичээдэг - серверийн кодын суурь нь 99%, үйлчлүүлэгчийн кодын бааз нь 95% орчим байдаг. 1C: Enterprise технологийн платформ нь үндсэндээ C++ хэл дээр бичигдсэн бөгөөд ойролцоогоор кодын шинж чанаруудыг доор өгөв.

  • 10 сая мөр C++ код,
  • 14 мянган файл,
  • 60 мянган анги,
  • хагас сая арга.

Мөн энэ бүх зүйлийг C++ 14 хэл рүү орчуулах шаардлагатай байсан. Өнөөдөр бид үүнийг хэрхэн хийсэн, энэ явцад юу тохиолдсон талаар танд хэлэх болно.

Бид 10 сая мөр C++ кодыг C++14 стандарт руу (дараа нь C++17 руу) хэрхэн хөрвүүлсэн бэ?

Хариуцлага

Төрөл бүрийн номын санд стандарт ангиудыг хэрэгжүүлснээр удаан/хурдан ажиллах, санах ойн их зарцуулалт (биш) тухай доор бичигдсэн бүх зүйл нь нэг зүйлийг илэрхийлдэг: энэ нь БИДНИЙ ТУХАЙ үнэн юм. Стандарт хэрэгжүүлэлт нь таны даалгаварт хамгийн тохиромжтой байх магадлалтай. Бид өөрсдийн даалгавраас эхэлсэн: бид үйлчлүүлэгчдийнхээ хувьд ердийн өгөгдлийг авч, тэдгээр дээр ердийн хувилбаруудыг ажиллуулж, гүйцэтгэл, ашигласан санах ойн хэмжээ гэх мэтийг харж, бид болон манай үйлчлүүлэгчид ийм үр дүнд сэтгэл хангалуун байгаа эсэхэд дүн шинжилгээ хийсэн. . Тэгээд тэднээс хамаарч ажилласан.

Бидэнд байсан зүйл

Эхлээд бид Microsoft Visual Studio дээр 1C: Enterprise 8 платформын кодыг бичсэн. Төсөл 2000-аад оны эхээр эхэлсэн бөгөөд бид зөвхөн Windows хувилбартай байсан. Мэдээжийн хэрэг, тэр цагаас хойш кодыг идэвхтэй боловсруулж, олон механизмыг бүрэн шинэчилсэн. Гэхдээ код нь 1998 оны стандартын дагуу бичигдсэн бөгөөд жишээлбэл, бидний зөв өнцгийн хаалтуудыг зайгаар тусгаарласан бөгөөд ингэснээр эмхэтгэл амжилттай болно, жишээ нь:

vector<vector<int> > IntV;

2006 онд платформ 8.1 хувилбар гарснаар бид Линуксыг дэмжиж, гуравдагч талын стандарт номын сан руу шилжсэн. STLPort. Шилжилтийн нэг шалтгаан нь өргөн шугамтай ажиллах явдал байв. Манай кодонд бид wchar_t төрөлд суурилсан std::wstring-г бүхэлд нь ашигладаг. Windows дээр түүний хэмжээ 2 байт, Линукс дээр анхдагч нь 4 байт байна. Энэ нь үйлчлүүлэгч болон серверийн хооронд манай хоёртын протоколуудын нийцэхгүй байдал, мөн янз бүрийн байнгын өгөгдөлд хүргэсэн. Gcc сонголтуудыг ашигласнаар эмхэтгэлийн явцад wchar_t-ийн хэмжээ мөн 2 байт байна гэж зааж өгч болно, гэхдээ дараа нь хөрвүүлэгчийн стандарт номын санг ашиглахаа мартаж болно. Энэ нь glibc-г ашигладаг бөгөөд энэ нь эргээд 4 байт wchar_t-д зориулж хөрвүүлэгддэг. Бусад шалтгаанууд нь стандарт ангиудыг илүү сайн хэрэгжүүлэх, хэш хүснэгтийг дэмжих, тэр ч байтугай бидний идэвхтэй ашигладаг савны дотор шилжих семантикийг эмуляци байсан. Бас нэг шалтгаан нь тэдний хамгийн сүүлд хэлсэнчлэн утсан гүйцэтгэл байсан. Бид утсанд зориулсан өөрийн гэсэн ангитай байсан, учир нь... Манай програм хангамжийн онцлогоос шалтгаалан мөрт үйлдлүүд маш өргөн хэрэглэгддэг бөгөөд бидний хувьд энэ нь маш чухал юм.

Манай мөр нь 2000-аад оны эхээр илэрхийлэгдсэн мөрийг оновчтой болгох санаан дээр суурилдаг Андрей Александреску. Хожим нь Александреску Facebook-т ажиллаж байхдаа түүний санал болгосноор ижил төстэй зарчмаар ажилладаг шугамыг Facebook хөдөлгүүрт ашигласан (номын санг үзнэ үү). мунхаглал).

Манай шугам нь хоёр үндсэн оновчтой технологийг ашигласан:

  1. Богино утгуудын хувьд стринг объектын дотоод буферийг ашигладаг (санах ойн нэмэлт хуваарилалт шаарддаггүй).
  2. Бусад бүхний хувьд механикийг ашигладаг Хуулах дээр бичих. Мөрийн утгыг нэг газар хадгалдаг бөгөөд хуваарилах/өөрчлөх үед лавлагааны тоолуурыг ашигладаг.

Платформын эмхэтгэлийг хурдасгахын тулд бид STLPort хувилбараасаа урсгалын хэрэгжилтийг хассан (бид үүнийг ашиглаагүй), энэ нь бидэнд 20% илүү хурдан эмхэтгэлийг өгсөн. Дараа нь бид хязгаарлагдмал ашиглах шаардлагатай болсон Тус дэм. Boost нь урсгалыг, ялангуяа үйлчилгээний API-д (жишээ нь, бүртгэлд) ихээхэн ашигладаг тул бид урсгалын хэрэглээг арилгахын тулд үүнийг өөрчлөх шаардлагатай болсон. Энэ нь эргээд Boost-ийн шинэ хувилбарууд руу шилжихэд хүндрэл учруулсан.

Гурав дахь зам

C++ 14 стандарт руу шилжихдээ бид дараах сонголтуудыг авч үзсэн.

  1. Бидний өөрчилсөн STLPort-г C++ 14 стандарт болгон шинэчил. Сонголт нь маш хэцүү, учир нь... STLPort-ийн дэмжлэгийг 2010 онд зогсоосон бөгөөд бид түүний бүх кодыг өөрсдөө бүтээх хэрэгтэй болно.
  2. C++ 14-тэй нийцтэй өөр STL хэрэгжилт рүү шилжих. Энэ хэрэгжилт нь Windows болон Linux-д зориулагдсан байх нь зүйтэй юм.
  3. Үйлдлийн систем бүрийг эмхэтгэхдээ харгалзах хөрвүүлэгчид суулгасан номын санг ашиглана уу.

Эхний хувилбар нь хэт их ажил хийснээс болж шууд татгалзсан.

Бид хоёр дахь хувилбарын талаар хэсэг хугацаанд бодсон; нэр дэвшигч гэж үздэг libc++, гэхдээ тэр үед Windows дээр ажиллахгүй байсан. libc++-г Windows руу шилжүүлэхийн тулд та маш их ажил хийх хэрэгтэй болно - жишээлбэл, libc++ нь эдгээр хэсэгт ашиглагдаж байгаа тул thread, thread синхрончлол, атомтай холбоотой бүх зүйлийг өөрөө бичих хэрэгтэй. POSIX API.

Тэгээд бид гурав дахь замыг сонгосон.

Шилжилт

Тиймээс бид STLPort-ийн хэрэглээг тохирох хөрвүүлэгчийн сангуудаар солих шаардлагатай болсон (Windows-д зориулсан Visual Studio 2015, Linux-д зориулсан gcc 7, macOS-д зориулсан clang 8).

Аз болоход, бидний код нь үндсэндээ зааврын дагуу бичигдсэн бөгөөд бүх төрлийн ухаалаг заль мэхийг ашиглаагүй тул төрөл, анги, нэрийн орон зай, эх сурвалжийн нэрийг орлуулсан скриптүүдийн тусламжтайгаар шинэ номын сан руу шилжих нь харьцангуй жигд явагдсан. файлууд. Шилжилт нь 10 эх файлд (000-аас) нөлөөлсөн. wchar_t-г char14_t-ээр сольсон; Бид wchar_t ашиглахаас татгалзахаар шийдсэн, учир нь char000_t нь бүх үйлдлийн систем дээр 16 байт багтаамжтай бөгөөд Windows болон Линуксийн хооронд кодын нийцтэй байдлыг алдагдуулдаггүй.

Жижигхэн адал явдал тохиолдсон. Жишээлбэл, STLPort дээр давтагчийг элементийн заагч руу шууд дамжуулж болох ба манай кодын зарим газар үүнийг ашигласан. Шинэ номын сангуудад үүнийг хийх боломжгүй болсон тул эдгээр хэсгүүдэд дүн шинжилгээ хийж, гараар дахин бичих шаардлагатай болсон.

Тиймээс кодын шилжилт дуусч, кодыг бүх үйлдлийн системд зориулж эмхэтгэсэн. Туршилт хийх цаг боллоо.

Шилжилтийн дараах туршилтууд кодын хуучин хувилбартай харьцуулахад гүйцэтгэл буурч (зарим газарт 20-30% хүртэл), санах ойн хэрэглээ (10-15% хүртэл) нэмэгдсэн байна. Энэ нь ялангуяа стандарт мөрүүдийн дутуу гүйцэтгэлтэй холбоотой байв. Тиймээс бид дахин бага зэрэг өөрчлөгдсөн шугамаа ашиглах шаардлагатай болсон.

Суулгасан номын сан дахь контейнеруудыг хэрэгжүүлэх сонирхолтой шинж чанар нь мөн илэрсэн: хоосон (элементгүй) std::map ба std:: суулгагдсан номын сангаас тогтоосон санах ойг хуваарилдаг. Хэрэгжүүлэх онцлогоос шалтгаалан кодын зарим газарт ийм төрлийн хоосон савнууд бий болсон. Стандарт санах ойн савыг нэг үндсэн элементийн хувьд бага зэрэг хуваарилдаг боловч бидний хувьд энэ нь маш чухал болсон - хэд хэдэн хувилбарт бидний гүйцэтгэл мэдэгдэхүйц буурч, санах ойн хэрэглээ нэмэгдсэн (STLPort-тай харьцуулахад). Тиймээс, бид өөрсдийн кодонд эдгээр хоёр төрлийн контейнерийг суулгасан номын сангаас Boost-ийн хэрэгжүүлэлтээр сольсон бөгөөд эдгээр контейнерт ийм функц байхгүй байсан бөгөөд энэ нь удаашруулж, санах ойн хэрэглээг нэмэгдүүлэх асуудлыг шийдсэн.

Томоохон төслүүдэд томоохон хэмжээний өөрчлөлт хийсний дараа ихэвчлэн тохиолддог шиг эх кодын эхний давталт нь асуудалгүй ажиллаагүй бөгөөд энд, ялангуяа Windows-ийн хэрэгжилт дэх давталтуудыг дибаг хийх дэмжлэг хэрэгтэй болсон. Бид алхам алхмаар урагшилж, 2017 оны хавар (хувилбар 8.3.11 1C: Enterprise) шилжилт хөдөлгөөн дууссан.

Үр дүн

С++14 стандарт руу шилжихэд бид 6 сар орчим хугацаа зарцуулсан. Ихэнх тохиолдолд нэг (гэхдээ маш өндөр мэргэшсэн) хөгжүүлэгч төсөл дээр ажиллаж байсан бөгөөд эцсийн шатанд тодорхой чиглэлийг хариуцдаг багуудын төлөөлөгчид нэгдсэн - UI, серверийн кластер, хөгжүүлэлт, удирдлагын хэрэгсэл гэх мэт.

Энэхүү шилжилт нь бидний стандартын хамгийн сүүлийн хувилбар руу шилжих ажлыг ихээхэн хялбаршуулсан. Тиймээс 1C: Enterprise 8.3.14 хувилбарыг (хөгжлийн шатандаа, ирэх оны эхээр гаргахаар төлөвлөж байна) стандарт руу аль хэдийн шилжүүлсэн байна. C++ 17.

Шилжүүлсний дараа хөгжүүлэгчид илүү олон сонголттой болно. Хэрэв бид өмнө нь STL-ийн өөрийн гэсэн өөрчилсөн хувилбар болон нэг std нэрийн орон зайтай байсан бол одоо std нэрийн талбар, stdx нэрийн талбарт суулгасан хөрвүүлэгчийн сангаас стандарт ангиуд - бидний даалгаварт оновчтой болгосон мөр, контейнерууд, нэмэгддэг. boost-ийн хамгийн сүүлийн хувилбар. Хөгжүүлэгч нь түүний асуудлыг шийдвэрлэхэд хамгийн тохиромжтой ангиудыг ашигладаг.

Хөдөлгөөнт бүтээгчийн "уугуул" хэрэгжилт нь хөгжилд тусалдаг (бүтээгчийг шилжүүлэх) хэд хэдэн ангиудад зориулагдсан. Хэрэв анги нь зөөвөрлөх үүсгэгчтэй бөгөөд энэ анги нь саванд байрлуулсан бол STL нь контейнер доторх элементүүдийн хуулбарыг оновчтой болгодог (жишээлбэл, савыг өргөтгөх, багтаамжийг өөрчлөх, санах ойг дахин хуваарилах шаардлагатай үед).

Асуудалтай нэг зүйл рүү нис

Шилжилт хөдөлгөөний хамгийн тааламжгүй (гэхдээ эгзэгтэй биш) үр дагавар нь бид эзлэхүүн нэмэгдэхтэй тулгарч байгаа явдал юм. obj файлууд, мөн бүх завсрын файлуудтай бүтээх бүрэн үр дүн нь 60-70 ГБ эзэлдэг. Энэ зан үйл нь орчин үеийн стандарт номын сангуудын онцлогтой холбоотой бөгөөд тэдгээр нь үүсгэсэн үйлчилгээний файлуудын хэмжээг бага шүүмжилдэг болсон. Энэ нь эмхэтгэсэн програмын үйл ажиллагаанд нөлөөлөхгүй, гэхдээ энэ нь боловсруулахад олон тооны таагүй байдал үүсгэдэг, ялангуяа эмхэтгэлийн хугацааг нэмэгдүүлдэг. Бүтээгч серверүүд болон хөгжүүлэгч машинууд дээрх сул зайд тавигдах шаардлага мөн нэмэгдэж байна. Манай хөгжүүлэгчид платформын хэд хэдэн хувилбар дээр зэрэгцэн ажилладаг бөгөөд хэдэн зуун гигабайт завсрын файлууд заримдаа тэдний ажилд хүндрэл учруулдаг. Асуудал нь тааламжгүй, гэхдээ тийм ч чухал биш, бид одоохондоо түүний шийдлийг хойшлууллаа. Үүнийг шийдэх нэг хувилбарын нэг нь технологи гэж үзэж байна эв нэгдлийг бий болгох (ялангуяа Google Chrome хөтөчийг хөгжүүлэхдээ үүнийг ашигладаг).

Эх сурвалж: www.habr.com

сэтгэгдэл нэмэх