2010-06-28 18 views
6

मैं मिनिक्स के जीएमटाइम फ़ंक्शन के स्रोत के दौरान हुआ। मुझे उस बिट में दिलचस्पी थी जिसने युग के बाद से साल की संख्या की गणना की थी। यहाँ कि बिट की हिम्मत कर रहे हैं:जीएमटाइम इस तरह कार्यान्वित क्यों किया जाता है?

http://www.raspberryginger.com/jbailey/minix/html/gmtime_8c-source.html

http://www.raspberryginger.com/jbailey/minix/html/loc__time_8h-source.html

#define EPOCH_YR 1970 
#define LEAPYEAR(year) (!((year) % 4) && (((year) % 100) || !((year) % 400))) 
#define YEARSIZE(year) (LEAPYEAR(year) ? 366 : 365) 

int year = EPOCH_YR; 

while (dayno >= YEARSIZE(year)) { 
    dayno -= YEARSIZE(year); 
    year++; 
} 

ऐसा लगता है कि एल्गोरिथ्म की तरह हे (एन), जहां n युग से दूरी है। इसके अतिरिक्त, ऐसा लगता है कि LEAPYEAR को प्रत्येक वर्ष – वर्तमान तिथियों के लिए दर्जनों बार और भविष्य में बहुत दूर तिथियों के लिए अलग-अलग गणना की जानी चाहिए। मैं एक ही बात करने के लिए निम्नलिखित कलन विधि था (ISO-9601 युग से इस मामले में (वर्ष 0 = 1 ईसा पूर्व) के बजाय यूनिक्स काल):

#define CYCLE_1 365 
#define CYCLE_4 (CYCLE_1 * 4 + 1) 
#define CYCLE_100 (CYCLE_4 * 25 - 1) 
#define CYCLE_400 (CYCLE_100 * 4 + 1) 

year += 400 * (dayno/CYCLE_400) 
dayno = dayno % CYCLE_400 

year += 100 * (dayno/CYCLE_100) 
dayno = dayno % CYCLE_100 

year += 4 * (dayno/CYCLE_4) 
dayno = dayno % CYCLE_4 

year += 1 * (dayno/CYCLE_1) 
dayno = dayno % CYCLE_1 

यह किसी भी तारीख के लिए हे (1) में चलाता है , और ऐसा लगता है कि यह 1 9 70 के करीब उचित तारीखों के लिए भी तेज होना चाहिए।

तो, यह मानते हुए कि मिनिक्स डेवलपर्स स्मार्ट लोग हैं जिन्होंने इसे कारण के लिए अपना रास्ता बनाया है, और शायद मैं सी के बारे में थोड़ा और जानता हूं , क्यूं कर?

+0

यह * लग रहा है * जैसे कि यह तेजी से होना चाहिए। आपको अपने आर्किटेक्चर के बारे में सोचना होगा और कितनी तेजी से गुणा जैसे कुछ निर्देश हैं और आपके पास एक शाखा भविष्यवाणी करने वाला कितना अच्छा है (अधिकांश बहुत अच्छे हैं)। @jim mcnamara के कुछ दिलचस्प परिणाम हैं। – BobbyShaftoe

उत्तर

2

यह शुद्ध अटकलें है, लेकिन शायद MINIX आवश्यकताओं कि थे है निष्पादन गति से अधिक महत्वपूर्ण, जैसे सादगी, समझ में आसानी, और एकता? कुछ कोड एक पाठ्यपुस्तक में मुद्रित किए गए थे, आखिरकार।

1

आपका विधि ध्वनि लगता है, लेकिन यह क्योंकि अब आप कई चक्र पर मध्य चक्र हैं यह EPOCH_YR = 1970 के लिए काम करने के लिए प्राप्त करने के लिए थोड़ा और अधिक मुश्किल है।

आप अगर आपको लगता है कि मामले के लिए एक समान है और देखें कि क्या यह अभी भी बेहतर है देख सकते हैं?

आप निश्चित रूप से सही है कि यह बहस का मुद्दा है कि क्या है कि gmtime() कार्यान्वयन किसी भी उच्च प्रदर्शन कोड में इस्तेमाल किया जाना चाहिए है कर रहे हैं। किसी भी तंग लूप में ऐसा करने में बहुत व्यस्त काम है।

+1

बस 0..1 9 70 से दिनों की संख्या घटाना काम करेगा। यह स्थिर रहेगा, एक और #define के रूप में संग्रहीत किया जा सकता है। –

+1

जैसा कि एडम ने कहा था, बस ऑफसेट को घटाकर उसे ठीक कर दिया जाएगा, हालांकि यह 32-बिट टाइमस्टैम्प को ओवरफ़्लो करेगा। युग को 2000 ईस्वी में स्थापित करना दोनों समस्याओं को ठीक करेगा, मुख्य गणना के पहले और बाद में एक अतिरिक्त ऑपरेशन की आवश्यकता होगी। तो 64-बिट टाइम स्टांप उपलब्ध हैं, आईएसओ साल शून्य शायद बेहतर है क्योंकि यह एक) एक ऑपरेशन की बचत होती है, ख) और अधिक स्पष्ट है, और ग) आसान कैलेंडर-अज्ञेयवाद दिन के सप्ताह है। दूसरी तरफ, यदि आप एक आधुनिक युग के साथ 32-बिट टाइमस्टैम्प के साथ फंस गए हैं, तो आप 100- और 400-वर्ष चक्रों को भी भूल सकते हैं, क्योंकि 2000 एक लीप वर्ष है और 1 9 00 और 2100 बाहर हैं सीमा का –

+0

@ थॉम स्मिथ 2000 वर्षों में # दिनों (~ 730k) 2^32 से नीचे है। न तो कोड स्निप सेकंड से संबंधित है। –

6

y2 Minix कोड के रूप में अपने कोड Ran के रूप में y1 सोलारिस 9 v245 & इस प्रोफाइलर डेटा मिला:

%Time Seconds Cumsecs #Calls msec/call Name 
    79.1 0.34 0.34 36966  0.0092 _write 
    7.0 0.03 0.37 1125566  0.0000 .rem 
    7.0 0.03 0.40 36966  0.0008 _doprnt 
    4.7 0.02 0.42 1817938  0.0000 _mcount 
    2.3 0.01 0.43 36966  0.0003 y2 
    0.0 0.00 0.43  4  0.  atexit 
    0.0 0.00 0.43  1  0.  _exithandle 
    0.0 0.00 0.43  1  0.  main 
    0.0 0.00 0.43  1  0.  _fpsetsticky 
    0.0 0.00 0.43  1  0.  _profil 
    0.0 0.00 0.43 36966  0.0000 printf 
    0.0 0.00 0.43 147864  0.0000 .div 
    0.0 0.00 0.43 73932  0.0000 _ferror_unlocked 
    0.0 0.00 0.43 36966  0.0000 memchr 
    0.0 0.00 0.43  1  0.  _findbuf 
    0.0 0.00 0.43  1  0.  _ioctl 
    0.0 0.00 0.43  1  0.  _isatty 
    0.0 0.00 0.43 73932  0.0000 _realbufend 
    0.0 0.00 0.43 36966  0.0000 _xflsbuf 
    0.0 0.00 0.43  1  0.  _setbufend 
    0.0 0.00 0.43  1  0.  _setorientation 
    0.0 0.00 0.43 137864  0.0000 _memcpy 
    0.0 0.00 0.43  3  0.  ___errno 
    0.0 0.00 0.43  1  0.  _fstat64 
    0.0 0.00 0.43  1  0.  exit 
    0.0 0.00 0.43 36966  0.0000 y1 

हो सकता है कि एक जवाब

+0

ऐसा लगता है कि लूप कार्यान्वयन 0secs में चलता है जहां 0.01 सेकंड में मॉड्यूलो कार्यान्वयन के रूप में। –

+0

बेंचमार्किंग करने के लिए निश्चित रूप से एक मामला। मैं इन परिणामों को देखने से पहले पूछताछ के कोड पर तेजी से शर्त लगाता। – ryyker

0

सही दृष्टिकोण। आप निश्चित रूप से ओ (1) अलगो के लिए जाना चाहते हैं। एडो के बिना माया कैलेंडर में काम करेंगे। अंतिम पंक्ति की जांच करें: dayno 0..364 तक सीमित है, हालांकि लीप वर्षों में इसे 0..365 तक की आवश्यकता है। रेखा पहले एक समान दोष है।

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