2010-11-10 6 views
10

मैं संरचना में डबल लपेटकर माप इकाइयों प्रणाली को कॉल करने की कोशिश कर रहा हूं। मेरे पास मीटर, द्वितीय, डिग्री इत्यादि जैसे सी # संरचनाएं हैं। मेरा मूल विचार यह था कि कंपाइलर के बाद सबकुछ रेखांकित किया गया है, मेरे पास एक प्रदर्शन होगा जैसे कि डबल का उपयोग किया जाता था।माप की इकाइयों को व्यक्त करने के लिए सी # प्रकारों का उपयोग

मेरे स्पष्ट और निहित ऑपरेटर सरल और सीधा हैं, और कंपाइलर वास्तव में उन्हें इनलाइन करता है, फिर भी मीटर और सेकेंड वाला कोड डबल कोड का उपयोग करके एक ही कोड से 10 गुना धीमा है।

मेरा प्रश्न यह है कि क्यों नहीं सी # कंपाइलर दूसरे का उपयोग करके कोड को दोहरा कर कोड के रूप में इष्टतम के रूप में बना सकता है यदि यह सब कुछ इनलाइन करता है?

दूसरा निम्नलिखित के रूप में परिभाषित किया गया है:

struct Second 
{ 
    double _value; // no more fields. 

    public static Second operator + (Second left, Second right) 
    { 
     return left._value + right._value; 
    } 
    public static implicit Second operator (double value) 
    { 
     // This seems to be faster than having constructor :) 
     return new Second { _value = value }; 
    } 

    // plenty of similar operators 
} 

अद्यतन:

यदि struct यहाँ फिट बैठता है मैं नहीं पूछा। ऐसा होता है।

मैंने नहीं पूछा कि कोड को रेखांकित किया जा रहा है या नहीं। जेआईटी इसे रेखांकित करता है।

मैंने रनटाइम में उत्सर्जित असेंबली ऑपरेशंस की जांच की। वे इस तरह कोड के लिए अलग अलग था:

var x = new double(); 
for (var i = 0; i < 1000000; i++) 
{ 
    x = x + 2; 
    // Many other simple operator calls here 
} 

और इस तरह:

var x = new Second(); 
for (var i = 0; i < 1000000; i++) 
{ 
    x = x + 2; 
    // Many other simple operator calls here 
} 

disassembly में कोई कॉल निर्देश थे, तो वास्तव में आपरेशन inlined रहे थे। फिर भी अंतर महत्वपूर्ण है। प्रदर्शन परीक्षण से पता चलता है कि दूसरा उपयोग करना डबल का उपयोग करने से 10 गुना धीमा है।

तो मेरे प्रश्न हैं (ध्यान!): ऊपर दिए गए मामलों के लिए जेआईटी जेनरेट आईए 64 कोड अलग क्यों है? स्ट्रक्चर को डबल के रूप में तेजी से चलाने के लिए क्या किया जा सकता है? ऐसा लगता है कि डबल और सेकेंड के बीच कोई सैद्धांतिक अंतर नहीं है, मैंने देखा अंतर का गहरा कारण क्या है?

+1

क्या यह 'निहित' या '+' ऑपरेटर है? –

+0

आपको इस संबंधित प्रश्न में रुचि हो सकती है: http://stackoverflow.com/questions/348853/units-of-measure-in-c-almost – Benjol

+1

मुझे पता है कि आप सी # का उपयोग कर रहे हैं, लेकिन क्या आपने एफ # माना है? यह स्थिर इकाइयों की जांच में बनाया गया है जो आपको लगता है कि आप किस तरह की तलाश में हैं। Http://stackoverflow.com/questions/40845/how-do-f-units-of-measure-work –

उत्तर

1

सी # संकलक कुछ भी इनलाइन नहीं करता है - JIT कर सकता है, लेकिन करने के लिए बाध्य नहीं है। यह अभी भी बहुत तेज होना चाहिए।

private readonly double _value; 
public double Value { get { return _value; } } 
public Second(double value) { this._value = value; } 
public static Second operator +(Second left, Second right) { 
    return new Second(left._value + right._value); 
} 
public static implicit operator Second(double value) { 
    return new Second(value); 
} 

JIT इनलाइन किए जाने वाले विशिष्ट परिदृश्यों तक सीमित है: के माध्यम से देखने के लिए एक और ऑपरेटर - मैं शायद + में निहित रूपांतरण हटा हालांकि (नीचे निर्माता उपयोग देखें)। क्या यह कोड उन्हें संतुष्ट करेगा? कहना मुश्किल है - लेकिन काम करना चाहिए और अधिकांश परिदृश्यों के लिए तेजी से काम करना चाहिए। + के साथ समस्या यह है कि युगल जोड़ने के लिए एक आईएल ओपोड है; यह लगभग नहीं काम करता है - जहां आपका कोड कुछ स्थिर तरीकों और एक कन्स्ट्रक्टर को कॉल कर रहा है; कुछ ओवरहेड होने पर भी हमेशा रेखांकित किया जा रहा है।

+0

मैंने एक 'int' को एक स्ट्रक्चर (फिक्स्ड-पॉइंट लागू करने) में लपेट लिया था और जब जिटर ने कोड को रेखांकित किया था (आईएमओ इसे कोड को अधिक आक्रामक रूप से इनलाइन करना चाहिए) तो यह सही असेंबली कोड उत्पन्न करता है। तो अगर रेखांकित किया गया है तो शायद कोई ओवरहेड नहीं है। – CodesInChaos

4

यह मेरी राय है, अगर आप असंतोष के बजाय असहमत हैं तो कृपया एक टिप्पणी लिखें।

सी # कंपाइलर इसे इनलाइन नहीं करता है। जेआईटी कंपाइलर हो सकता है, लेकिन यह हमारे लिए अनिश्चित है, क्योंकि जिटर का व्यवहार सीधा नहीं है।

double के मामले में कोई ऑपरेटर वास्तव में नहीं आते हैं। ओपोड add का उपयोग कर संचालन को स्टैक में जोड़ा जाता है। आपके मामले की विधि में op_Add प्लस तीन struct स्टैक से कॉपी करने के लिए लगाया जाता है।

class के साथ struct को बदलने के साथ इसे अनुकूलित करने के लिए प्रारंभ करें। यह कम से कम प्रतियों की मात्रा कम करेगा।

+2

... और structs आपको रास्ते में परेशानी में मिल जाएगा। –

+0

आप structs के बजाय यहां कक्षाओं का उपयोग क्यों करना चाहते हैं? अगर वह 'वर्ग' का उपयोग करता है तो उसके अपहरण (ऑपरेटरों और प्रकारों की विशाल मात्रा) में समस्याएं नहीं बदलेगी लेकिन प्रदर्शन शायद बहुत कम हो जाएगा। – CodesInChaos

+0

@CodeInChaos मैं कभी भी 'struct' का उपयोग नहीं करता हूं। मुझे सच में लगता है कि इसे केवल इंटरऑप के साथ इस्तेमाल किया जाना चाहिए। "प्रदर्शन शायद बहुत कम हो जाएगा" क्यों? कृपया समझाईए। – Andrey

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

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