टेम्प्लेट के साथ काम करते समय आप तेजी से लंबे संकलन समय को कैसे संभालते हैं?


13

मैं विज़ुअल स्टूडियो 2012 का उपयोग करता हूं और उनके पास ऐसे मामले हैं जहां हमने "सीम पॉइंट" को पेश करने के लिए एक वर्ग "बस" में टेम्प्लेट मापदंडों को जोड़ा ताकि यूनिट-टेस्ट में हम उन हिस्सों को नकली वस्तुओं से बदल सकें।

आप आमतौर पर सी ++ में सीम पॉइंट कैसे पेश करते हैं: इंटरफेस और / या मिश्रण का उपयोग करके कुछ मापदंडों के आधार पर टेम्पलेट्स मापदंडों का भी उपयोग करके अंतर्निहित इंटरफेस के साथ? यह पूछने का एक कारण यह भी है क्योंकि जब कभी-कभी एक एकल C ++ फ़ाइल (जिसमें टेम्प्लेट फ़ाइलें शामिल होती हैं, जिसमें अन्य टेम्प्लेट भी शामिल हो सकते हैं) का संकलन किसी ऑब्जेक्ट फ़ाइल में उत्पन्न होता है जो किसी डेवलपर मशीन पर लगभग 5-10 सेकंड के क्रम में होता है। ।

VS कंपाइलर भी खासतौर पर कम्पाइलिंग टेम्प्लेट्स पर ज्यादा तेज नहीं है, जहां तक ​​मैं समझता हूं, और टेम्प्लेट शामिल किए जाने के मॉडल के कारण (आप व्यावहारिक रूप से हर फाइल में टेम्प्लेट की परिभाषा शामिल करते हैं जो इसे अप्रत्यक्ष रूप से उपयोग करता है और संभवत: उस टेम्पलेट को हर बार जब आप संशोधित करते हैं ऐसा कुछ जिसका उस खाके से कोई लेना-देना नहीं है) आपको संकलन के समय (जब वृद्धिशील संकलन करते हुए) से समस्या हो सकती है।

वृद्धिशील से निपटने के आपके तरीके क्या हैं (और न केवल) संकलन समय जब टेम्पलेट्स के साथ काम करते हैं (एक बेहतर / तेज संकलक के अलावा :-))।


1
@RobertHarvey निर्भरता इंजेक्शन टेम्पलेट मापदंडों का उपयोग करके बनाया गया है। उत्पादन कोड में, जहां मैं इनको तुरंत करता हूं, मेरे पास धीमा संकलन समय है।
गीता

5
क्या आप C ++ 11 का उपयोग कर रहे हैं? देख en.wikipedia.org/wiki/C%2B%2B11#Extern_template
mike30

2
चूंकि आंद्रेई अलेक्जेंड्रेस्कु के पास "मॉडर्न सी ++ डिज़ाइन" है, बहुत सारे सी ++ प्रोग्रामर को लगता है कि उन्हें सभी और सभी चीज़ों के लिए टेम्प्लेट का उपयोग करना चाहिए और कंपाइलर को अधिक से अधिक संभालना चाहिए। यह आमतौर पर उन प्रभावों की ओर ले जाता है जिनका आप वर्णन कर रहे हैं। पूर्व में (और वर्तमान में अन्य भाषाओं का उपयोग करने वाले प्रोग्रामर के लिए), यह टेम्प्लेट का उपयोग न करना और रन टाइम मैकेनिक के साथ निर्भरता इंजेक्शन जैसी चीजों को संभालना बिल्कुल ठीक था, भले ही इसके लिए अंत उपयोगकर्ता के लिए कुछ सीपीयू चक्रों की अधिक आवश्यकता हो (जिसे वह लगभग कभी नोटिस नहीं करेगा। )। ईमानदारी से, मुझे यकीन है कि रॉबर्ट 100% सही हैं और जिस तरह से आप इसके बारे में सोचते हैं, वह वैसा ही है।
डॉक्टर ब्राउन

1
@ गीता: टेम्पलेट मेटा प्रोग्रामिंग का उपयोग करते हुए IMHO अक्सर समयपूर्व अनुकूलन (और कभी-कभी सिर्फ ओवरकिल) का एक रूप है - जहाँ तक आप तुलनीय आवश्यकताओं के साथ एसटीएल की तरह काम नहीं लिखते हैं। आप बड़े संकलन समय, कम रख-रखाव और हार्ड-टू-समझने त्रुटि संदेशों के लिए कुछ प्रदर्शन-लाभ का व्यापार करते हैं। "एक्सटर टेम्प्लेट" का उपयोग करने से आपको अल्पकालिक पर मदद मिल सकती है, लेकिन अगर मैं आपके जूते में था, तो मैं दीर्घकालिक सुधारों के बारे में भी सोचूंगा।
डॉक्टर ब्राउन

4
@DocBrown। इसके विपरीत, आप कह सकते हैं कि निर्माण को बेहतर बनाने के लिए टेम्पलेट्स से बचना एक समय से पहले का अनुकूलन है। कई समस्याओं के लिए टेम्पलेट आदर्श सार हैं।
20:30 बजे mike30

जवाबों:


9

यदि आपके टेम्प्लेट पैरामीटर केवल मानों के एक परिमित (और छोटे) सेट कर सकते हैं, तो आप उनकी परिभाषा को स्रोत फ़ाइल में स्थानांतरित कर सकते हैं, और त्वरित इंस्ट्रूमेंटेशन का उपयोग कर सकते हैं ।

उदाहरण के लिए, aaa.hआप केवल टेम्प्लेट फ़ंक्शंस घोषित करते हैं fऔर g:

template <int n>
int f();

template <class T>
void g(int a);

मान लें कि nटेम्प्लेट पैरामीटर केवल 1, 3, 6 हो सकता है, और Tटेम्प्लेट पैरामीटर केवल हो सकता है int, longऔर void *

फिर आप उन्हें aaa.cppइस तरह से परिभाषित करते हैं :

template <int n>
int f()
{
    ...
}

template <class T>
void g(int a)
{
    ...
}

template int f<1>();
template int f<3>();
template int f<6>();

template void g<int>(int a);
template void g<long>(int a);
template void g<void *>(int a);

इस प्रकार संकलक संकलन करते समय दिए गए मापदंडों का खाका तैयार करता है aaa.cpp। क्लाइंट कोड को संकलित करते समय, यह मान लिया जाता है कि परिभाषाएँ कहीं मौजूद हैं, और लिंक करने वाला इसका ध्यान रखेगा।

#include "aaa.h"

int main()
{
    f<1>();
    f<3>();
    f<6>();

    g<int>(5);
    g<long>(5);
    g<void *>(5);
}

आप स्पष्ट रूप से टेम्पलेट कक्षाओं को भी तुरंत कर सकते हैं। दोष यह है कि आप उपयोग नहीं कर सकते हैं fया gअन्य टेम्पलेट मापदंडों के साथ।

#include "aaa.h"

int main()
{
    f<5>();
}

का परिणाम

undefined reference to `int f<5>()'

मैंने इस तकनीक का उपयोग एक ऐसी परियोजना में किया, जिसमें कुछ जटिल कक्षाएं पूर्णांक टेम्पलेट मापदंडों के एक छोटे (<10) सेट पर निर्भर करती थीं, और यह संकलन समय को काफी कम कर देता था (चूंकि कंपाइलर को क्लाइंट कोड का संकलन करते समय जटिल टेम्पलेट परिभाषाओं को पार्स नहीं करना पड़ता था) । बेशक आपको वास्तविक कोड के आधार पर कम सुधार मिल सकता है।


2

एक बार मैंने इसी तरह की समस्या के लिए एक अजीब समाधान का उपयोग किया: एसटीएल लीड को संकलित करने के लिए प्रति सेकंड कई सेकंड की तरह स्रोत फ़ाइल शामिल है - कोई फर्क नहीं पड़ता कि यह कितना छोटा था। इसलिए मैंने अपनी सभी स्रोत फ़ाइलों को एक मास्टर फ़ाइल में शामिल किया और प्रति फ़ाइल संकलन समय शायद ही बदल गया ... जिसका मतलब था कि कारक 20+ की गति, क्योंकि मेरे पास संकलन के लिए केवल एक फ़ाइल थी।

डिज़ाइन को साफ रखने के लिए मैंने एक मेकफाइल बनाए रखना जारी रखा, लेकिन वास्तव में इसका इस्तेमाल नहीं किया (सिवाय इसके अभी भी काम करने के लिए)।


0

हम अपने पूर्वगामी हेडर और precompiled टेम्पलेट रातोंरात बनाने के लिए एक बड़े कार्य को आग लगाते थे, और बस अगले दिन उन लोगों के खिलाफ निर्माण करते थे।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.