2011-07-03 14 views
12

अगर मैं लिखनासंकलन समय मूल्यांकन

enum chars = digits ~ uppercase; 

स्ट्रिंग संकलन समय पर श्रेणीबद्ध किया जाएगा? मुझे लगता है कि यह होगा। यदि मैं इसे एक स्ट्रिंग अक्षर या सीटीएफई फ़ंक्शन के साथ प्रतिस्थापित करता हूं तो मैं किसी भी महत्वपूर्ण प्रदर्शन अंतर को माप नहीं सकता (यहां तक ​​कि इसे सौ मिलियन बार भी बुला रहा हूं)। अगर मैं कॉन्स के साथ enum को प्रतिस्थापित करता हूं तो मुझे एक फर्क पड़ता है। मुझे बताया गया है कि इसे इस तरह लिखने में अक्षम है। मैंने सोचा कि यह सुविधाजनक था और मुझे अक्षमता दिखाई नहीं दे रही है। (बीटीडब्ल्यू, रेखा एक समारोह में है जिसे रिकर्सिवली कहा जाता है)।

पूर्ण कोड

import std.string; 

string toBase(long n, int b) 
in { 
    assert(2 <= b && b <= 35); 
} body { 
    static string sign; 
    if (n < 0) { 
     n *= -1; 
     sign = "-"; 
    } 
    enum chars = digits ~ uppercase; 
    size_t r = cast(size_t)(n % b); 
    if (n == r) { 
     return sign ~ chars[r]; 
    } 
    return toBase((n - r)/b, b) ~ chars[r]; 
} 

संपादित करें (एक अलग आधार के साथ एक अंक प्रणाली को बदलने): अपडेट किए गए कोड, टिप्पणी के जवाब में, सवाल

string toBase(long n, int b) 
in { 
    assert(2 <= b && b <= 35); 
} body { 
    enum chars = digits ~ uppercase; 
    long r = n % b; 
    char c = chars[cast(size_t) abs(r)]; 
    if (n == r) { 
     return (n < 0 ? "-" : "") ~ c; 
    } 
    return toBase((n - r)/b, b) ~ c; 
} 
+2

आप साइन स्ट्रिंग को रीसेट करने के लिए भूल गए हैं (आप 'स्कोप (निकास) साइन = "" का उपयोग कर सकते हैं; "इसके लिए' toBase (-10,10) '' toBase (10,10) 'दे देंगे एक ही परिणाम –

+0

सही। हा हा हा, पहली बार मैं एक स्थिर चर का उपयोग करें। मुश्किल। वह गुंजाइश (निकास) चीज वास्तव में उपयोगी है ना? मुझे आश्चर्य है कि एक रिकर्सिव कॉल एक गुंजाइश निकास के रूप में योग्य नहीं है। – fwend

+1

एक स्कोप (निकास) निष्पादित किया जाता है जब वर्तमान स्टैक फ्रेम स्टैक से पॉप किया जाता है (जैसे प्रयास करें ... आखिर में वास्तव में लेकिन बिना अतिरिक्त इंडेंटेशन के) रिकर्सन ऐसा नहीं करता है –

उत्तर

9

enum instantiations तरह के लिए प्रासंगिक नहीं हमेशा संकलन-समय पर मूल्यांकन किया गया है (और संकलन समय पर मूल्यांकन असंभव है जब संकलन त्रुटियों को फेंक दें)

इसलिए संकलन समय पर संगतता की जाती है और कोड में एक अपरिवर्तनीय संस्करण संग्रहीत किया जाता है और रनटाइम

5

खुद को जांचने का एक तरीका है कि स्ट्रिंग को संकलित समय पर संयोजित किया गया है या नहीं, कोड को संकलित करना और जांच करना ऑब्जेक्ट फ़ाइल आपकी फ़ाइल मान लिया जाये कि test.d कहा जाता है:

Contents of section .rodata: 
0000 2d000000 00000000 00000000 00000000 -............... 
0010 01000000 00000000 00000000 00000000 ................ 
0020 30313233 34353637 38394142 43444546ABCDEF 
0030 4748494a 4b4c4d4e 4f505152 53545556 GHIJKLMNOPQRSTUV 
0040 5758595a 00000000 00000000 00000000 WXYZ............ 
0050 24000000 00000000 20000000 00000000 $....... ....... 

(यह लिनक्स पर है, अन्य प्लेटफार्मों पर, आप वस्तु फ़ाइल का निरीक्षण करने के लिए विभिन्न उपकरणों की आवश्यकता होगी:

dmd -c test.d 
objdump test.o | grep -C3 "" 

... की तरह कुछ का उत्पादन करना चाहिए ।)

आप अपनी कोई उत्पादन enumconst करने के लिए या string, आप होगा (शायद) पाने को बदलते हैं: grep खोजने के लिए के लिए कोई concatenated स्ट्रिंग नहीं होगा।

लेकिन संकलक संकलन समय पर तारों को जोड़ सकता है जब भी enum का उपयोग नहीं किया जाता है। इस कार्यक्रम पर विचार करें:

import std.stdio; 

enum a = "Aaaa"; 
enum b = "Bbbb"; 
enum c = "Cccc"; 

void main() 
{ 
    enum x = a ~ b; 
    const y = b ~ a; 
    string z = a ~ c; 
    writeln(x, y, z); 
} 

अब, यह संकलन, और वस्तु फ़ाइल का परीक्षण:

% dmd -c test2.d && objdump -s test2.o | egrep "(Aaaa|Bbbb)" 
0000 42626262 41616161 00000000 00000000 BbbbAaaa........ 
0020 41616161 43636363 00000000 00000000 AaaaCccc........ 
0040 41616161 42626262 00000000 00000000 AaaaBbbb........ 

हम देखते हैं कि x, y और z सभी स्थैतिक शाब्दिक हैं। (मार्क a, b और cconst बजाय enum के रूप में, और आप अलग व्यवहार देख सकते हैं।) तो, enum संकलन समय मूल्यांकन की गारंटी है, जबकि, enum के अभाव संकलन-टाइम मूल्यांकन नहीं रोकता है।

संबंधित मुद्दे