هناك ملاحظة معروفة عن الانتظار: تحت عشر ثوان، تبقى مركزاً؛ بعد دقيقة، تبديل السياق وفقدان الخيط. أوقات البناء جالس بالضبط في هذا النطاق الخطر. دقيقة وثلاثين ثانية من التجميع لا تكلف فقط دقيقة وثلاثين ثانية — تكلف إعادة تحميل كل شيء كنت تعقده في رأسك عندما عادت من الحلقة التي تحولت. اضرب بخمسين أبنية يومياً عبر الفريق وأبنية بطيئة توقف أن تكون عدم راحة وتبدأ شكل السلوك: تعديلات أكبر وأكثر خطورة لأن التكرار مكلف، وتقليل إعادة البناء لأن حلقة التغذية المرتجعة تعاقبها، والاختبارات التي يتم تخطيها محلياً لأنها تأخذ وقتاً طويلاً.
الشيء المشجع حول أداء البناء في 2026 هو أن الانتصارات الأكبر عادة ما تكون إعدادات، وليس هندسة. لا تحتاج إلى إعادة هيكلة قاعدة الكود الخاصة بك؛ يمكنك تثبيت بعض الأدوات التي تعالج المراحل الثلاث المميزة حيث ينقضي الوقت فعلاً. يغطي هذا الدليل هذه المراحل — التجميع والربط والاختبار — عبر sccache و mold و cargo-nextest و bacon للحلقة الداخلية، والأهم، كيفية قياس ما إذا ساعد أي من ذلك فعلاً.
قياس قبل التحسين
الخطأ الأكثر شيوعاً الواحد هو تحسين المرحلة الخاطئة. "البناء بطيء" ليس تشخيصاً — البناء هو على الأقل التجميع والربط والاختبار (إذا كنت تشغّلها)، والتوازن بينها يختلف بشكل كبير حسب المشروع. قاعدة كود مع العديد من الصناديق الصغيرة وملف ثنائي نهائي ضخم قد تنفق معظم وقتها ربط؛ واحد مع generics ثقيلة و macros قد تهيمن عليه التجميع؛ مشروع ناضج قد تنفق أكثر من الوقت في الاختبارات من في إما.
لذا ابدأ مع كسر توقيت بدلاً من تخمين. في Rust، cargo build --timings ينتج تقرير HTML يظهر بالضبط كم من الوقت استغرق كل صندوق وأين جمود parallelism — غالباً ما تكشف أن تبعية واحدة متسلسل كل شيء آخر. لعرض خشن أكثر، time cargo build على شجرة نظيفة مقابل واحد متزايد يخبرك كم أنت تدفع لأبنية باردة. و hyperfine يعطيك مقارنات قبل/بعد معقولة إحصائياً بدلاً من التشغيل الواحد الصاخب الذي يسهل خداع نفسك معه.
هذا مهم لأن كل أداة أدناه تعالج مرحلة واحدة ولا تفعل شيء للآخرين. تثبيت محرر أسرع عندما يكون الاختناق الخاص بك التجميع ينتج خطأ وجهة نظر كاذبة للتقدم.
التجميع: توقف عن إعادة بناء ما جمعته بالفعل
المصدر الأكثر شيوعاً لهدر في التجميع هو التكرار — بناء نفس صندوق التبعية، مع نفس الأعلام، الذي أنت أو زميل أو عداء CI بالفعل جمعت قبل ساعة. sccache يعالج هذا مباشرة: فهو يلف المجمع، يجزئ المدخلات، وعودة تحفة مخزنة مؤقتاً عندما تكون قد رأت هذا التجميع الدقيق من قبل. وهو يدعم Rust و C/C++ و CUDA.
ما يرفع sccache يتجاوز ذاكرة محلية هي محركات التخزين المشتركة — S3, GCS, Redis, أو GitHub Actions cache. هذا يغيّر اقتصاديات CI على الخصوص. تجربة CI الافتراضية هي ماكينة باردة تجمّع كل تبعية من الصفر في كل تشغيل، وهو هدر محض لأن تلك التبعيات لم تتغير. مع ذاكرة مشتركة، التشغيل الأول يملأها وكل التشغيل اللاحق تحميل بدلاً من التجميع. الفريق يرى عادة أوقات بناء CI تسقط بنسبة نصف أو أكثر، وتخدم نفس الذاكرة آلات المطورين.
الإعداد هو متغير بيئة واحد (RUSTC_WRAPPER=sccache) أو دخول ~/.cargo/config.toml. المتابعة المهمة هي التحقق: sccache --show-stats يقرير معدل الضربة الخاص بك، و معدل منخفض هو إشارة أن شيء ما في المدخلات الخاصة بك يختلف — غير مستقرة RUSTFLAGS أو مسارات مطلقة مخبوزة في الإخراج أو التجميع المتزايد التداخل. ذاكرة بمعدل ضربة ضعيفة أسوأ من لا أحد، لأنك تدفع تكلفة البحث لا شيء.
الربط: الذيل المتسلسل
الربط هي المرحلة الناس تنسى، وغالباً ما تكون أسوأ المخالف في حلقة التحرير والتجميع والتشغيل. هنا لماذا: التجميع parallelizes جميلة عبر النوى، لكن الربط تقليدياً لا. تجمّع مائتي ملف عبر ستة عشر نوى في عشرين ثانية، ثم انتظر ثماني ثوان بينما نوى واحدة ترابط. في إعادة البناء المتزايدة — حيث غيّرت ملف واحد وذلك الملف فقط يعاد تجميعه — الربط يمكن أن يكون معظم انتظرك.
mold هو محرر قطرة في النهاية تم تصميمه من البداية لاستخدام كل النوى المتاحة. فهو عادة يقطع أوقات الربط بكمية من الحجم، والأن أن يهبط كسب مباشرة في مسار إعادة البناء المتزايد، فهي التغيير المطورون يشعرون فوراً. الاعتماد حقيقي تافه: mold -run cargo build يلف أي أمر بناء بدون إعدادات، أو يمكنك إضافة -fuse-ld=mold إلى أعلام linker الخاصة بك للإعداد الدائم.
السبب لدمج mold مع sccache هو أنهم يهاجمان نصفي مختلفين من نفس الانتظار. sccache يزيل التجميع الذي فعلته من قبل؛ mold يسرع الربط الذي يبقى ولا يمكن تخزين مؤقتًا. لا ينوب أحدهما الآخر، و معاً يُنتجان عادة تحسناً أكبر من أي واحد وحده.
الاختبار: العزلة والإخفاقات الصادقة
المرحلة الثالثة هي الاختبارات، و هنا cargo-nextest يغيّر النموذج بدلاً من فقط السرعة. cargo test القياسي يشغّل جميع الاختبارات في ملف ثنائي داخل عملية واحدة؛ nextest يشغّل كل اختبار في عملية خاصة به. الذي ينتج عنه عدة نتائج يتجاوز التسريع 2–3x النموذجي.
العزلة تصبح حقيقية. الاختبارات لا يمكنها أن تفسد حالة عام بعضها، لذا إخفاق معتمد على الترتيب يسطح فوراً بدلاً من الظهور بغموض أشهر لاحقاً. الحطام يمكن أن يُنسب — إذا تحطم اختبار أو انقطع، تتعلم أيه، بدلاً من فقدان نتائج الملف الثنائي كاملة. اختبارات غير مستقرة يتم تسميتها كما هي: مع --retries, اختبار يفشل ثم يمرر هو اليقين FLAKY بدلاً من تمرير بقار بهدوء، والذي يهم لأن اختبار غير مستقر هي مشكلة مختلفة من واحد فاشل وإخفاء ذلك هو كيفية تعفن المجموعات. و تجزئة CI مدمجة عبر --partition، بحيث تقسيم مجموعة عبر العدّائين علم بدلاً من مشروع سكريبتينج.
الفجوة الرئيسية للمعرفة: nextest لا تشغّل doctests، بحيث يكون نمط CI الشائع cargo nextest run && cargo test --doc.
حلقة داخلية: لا تشغّل الأبنية يدويًا
أسرع بناء هو واحد لم تضطر لاستدعاء. bacon يشغّل في محطة جانبية ويراقب مصدرك وينفذ cargo check أو clippy أو اختباراتك في كل حفظ وعرض ملخص خطأ مضغوط دائم الحالية. الكسب ليس سرعة خام — إنه أن التجميع يتداخل مع تفكيرك بدلاً من منعه، وترى الخطأ الأول بشكل بارز بدلاً من الإخراج المتمرر.
هذا يقترن بشكل طبيعي مع أدوات المرحلة: bacon توفر التغذية المرتجعة المستمرة، sccache و mold اجعل كل من تلك الخلفية تشغّل سريعة بما يكفي لإنهاء قبل انتهاء قراءة الخطأ السابق. للمشاريع غير-Rust, watchexec يوفر نفس نمط التغذية المرتجعة المستمرة لأي أمر.
تجميع معاً والتحقق
إعداد كامل هو قصير:
cargo install sccache cargo-nextest bacon --locked
sudo apt install mold # أو brew install mold
# ~/.cargo/config.toml
[build]
rustc-wrapper = "sccache"
[target.x86_64-unknown-linux-gnu]
linker = "clang"
rustflags = ["-C", "link-arg=-fuse-ld=mold"]
ثم تحقق من كل قطعة بشكل مستقل، لأن سوء إعدادات صامت سهل: sccache --show-stats يجب أن يعرض معدل ضربة متسلق؛ readelf -p .comment ./target/debug/yourbin | grep -i mold يؤكد mold ربط فعلاً؛ cargo nextest run يجب أن ينتهي مرئياً أسرع من cargo test. قياس النتيجة النهاية مع hyperfine على تغيير واقعي — لمس ملف واحد، إعادة بناء — بدلاً من على بناء نظيف، لأن الأبنية المتزايدة هي ما تفعله فعلاً طوال اليوم.
في CI، أضف محرك الذاكرة المشتركة (SCCACHE_GHA_ENABLED=true على GitHub Actions، أو دلو S3) واستخدم --partition nextest لتجزئة عبر العدّائين. CI هو حيث تدفع هذه الأدوات من خلال بشكل درامي، لأن آلات CI باردة افتراضياً وتكرر نفس العمل المهدور في كل تشغيل.
ما وراء الإعدادات: ما يجعل الأبنية بطيئة فعلاً
إذا كنت تطبيق أدوات المرحلة والحلقة لا تزال مؤلمة، الأسباب المتبقية بنيوية — وتستحق الفهم حتى لو قررت عدم التصرف بناءً عليها، لأنها تشرح لماذا بعض المشاريع تقاوم التحسين.
عدد التبعيات والعمق هو الأكثر شيوعاً. كل صندوق تبعية يجب أن يجمّع على الأقل مرة واحدة، و رسم بياني تبعية عميق متسلسل: لا يمكن لصندوق C أن يبدأ حتى انتهي B، والذي انتظر A. cargo build --timings يعرض هذا مباشرة كمسار حرج طويل مع نوى خاملة. القيام ببحث عن التبعيات التي تستخدمها trivially — سحب صندوق كبير لدالة مساعدة واحدة — غالباً ما يكون أعلى رافعة الإصلاح البنيوي، ويقلل سطح Supply-chain في نفس الوقت.
الرمز الجنرالي الثقيل و macro بتكلفة وقت التجميع بالتناسب مع التثبيت. دالة جنرالية تستخدم مع عشرين نوع تجمّع عشرين مرة، و macros إجرائية ثقيلة تشغّل رمز تعسفي في وقت التجميع. حيث جنرالية ساخنة لا تحتاج لأن تكون جنرالية، monomorphizing يدويًا أو تضييق حدودها يمكن قطع وقت التجميع بقياس. هذا هو تجارة حقيقية ضد ergonomics، لذا قياس قبل contort API.
حبيبات صندوق يقطع كلاهما. صندوق واحد ضخم لا يمكنه parallelize داخليًا ويفرض إعادة بناء كاملة لتعديلات صغيرة؛ مئات من صناديق tiny تضيف الكلفة لكل صندوق وسلسلة تبعية أعمق. الكلاوي المفيد هو تقسيم على طول حدود تغيير بمعدلات مختلفة — الرمز الأساسي المستقر في صندوقه الخاص بحيث تعديلات للرمز المتقلب لا تعيد بناء ذلك.
معلومات التصحيح وإعدادات التحسين هي أرخص رافعة البناء الهيكلي. معلومات التصحيح الكاملة مكلفة لتوليد وربط؛ debug = 1 (جداول الأسطر فقط) غالباً ما يكون كافياً لآثار الحزم بنسبة جزء من الكلفة. و للتبعيات لا تطأ كل شيء، opt-level overrides في ملف تعريف يسمح لك بتحسين رمزك الخاص بدون دفع لتحسين كل شيء.
لا أحد من هذه تغييرات إعدادات، وهذا لماذا تنتمي بعد الأدوات. لكن عندما يبقى المشروع بطيئاً رغم التخزين المؤقت والمحرر السريع، الإجابة هي تقريباً دائماً في هذه القائمة.
معرفة متى تتوقف
تحذير إغلاق: تحسين البناء نفسه هو مهمة مع تناقص العودات، وهو يستثنائياً جيد في الشعور منتجاً. مرة واحدة إعادة البناء المتزايدة الخاصة بك بضع ثوان، مزيد من الضبط يشتري قليل، والروافع المتبقية تصبح بشكل تدريجي أكثر intrusive — إعادة هيكلة حدود الصندوق وقطع التبعيات وإعادة الصيغة generics. تلك يمكن أن تكون تستحق القيام بها، لكنها مشاريع هندسية مع مخاطرة حقيقية، وليس تغييرات إعدادات.
التسلسل الصادق هو: قياس أولاً، تطبيق الإصلاحات الرخيصة الخاصة بالمرحلة (ذاكرة مشتركة، محرر، عداء اختبار)، قياس مرة أخرى، وتوقف عندما الحلقة لم تعد تقطع التركيز الخاص بك. الهدف لم يكن أبداً رقم benchmark — كان ذلك البقاء في التدفق طويل بما يكفي لإنهاء الفكرة التي كنت تملكها عندما اضغط الحفظ.
الخط السفلي
الأبنية البطيئة غير السلوك، وليس الجداول الزمنية فقط، وأكبر الإصلاحات في 2026 إعدادات بدلاً من الهندسة. تشخيص المرحلة التي فعلاً بتكلفك — cargo build --timings و hyperfine تفوز الحدس — ثم تطبيق الأداة التي تعالجها: sccache لتوقف إعادة تجميع ما أنت أو CI بالفعل بنيت، mold لـ parallelize الربط المتسلسل الذي يهيمن على الأبنية المتزايدة، cargo-nextest لاختبارات أسرع والمعزولة وغير مستقرة مع تجزئة CI مدمجة، و bacon بحيث التجميع يحدث بينما تفكر بدلاً من أثناء انتظرك. تحقق من أن كل واحد حقاً engaged، تطبيق الذاكرة المشتركة في CI حيث الهدر أكبر، وتوقف التحسين مرة واحدة الحلقة توقف قطع عليك.
المراجع والموارد
الأدوات
الخلفية والتحليل
أوراق cheatsheet ذات صلة بـ 1337skills