यह वास्तव में प्रोसेसर पर निर्भर करेगा, और पूर्णांक जो बेहतर है की सीमा (और double
का उपयोग कर सीमा मुद्दों के सबसे हल होगा) x86-64 और एआरएम तरह
आधुनिक "बड़ी" सीपीयू के लिए, पूर्णांक विभाजन और फ़्लोटिंग प्वाइंट डिवीजन मोटे तौर पर एक ही प्रयास है, और एक फ्लोट या इसके विपरीत एक पूर्णांक को परिवर्तित करना "कठिन" कार्य नहीं है (और कम से कम उस रूपांतरण में सही राउंडिंग करता है), इसलिए परिणामस्वरूप ऑपरेशन कर रहे हैं।
atmp = (float) a;
btmp = (float) b;
resfloat = divide atmp/btmp;
return = to_int_with_rounding(resfloat)
लगभग चार मशीन निर्देश।
दूसरी ओर, आपका कोड दो विभाजन, एक मॉड्यूलो और एक गुणा का उपयोग करता है, जो इस तरह के प्रोसेसर पर काफी अधिक संभावना है।
tmp = a/b;
tmp1 = a % b;
tmp2 = tmp1 * 2;
tmp3 = tmp2/b;
tmp4 = tmp + tmp3;
तो पाँच निर्देश है, और उन में से तीन "विभाजन" हैं (जब तक संकलक काफी चालाक a % b
के लिए a/b
का पुन: उपयोग करने के लिए है - लेकिन यह अभी भी दो अलग-अलग विभाजित है)।
बेशक, यदि आप अंकों की संख्या के बाहर हैं जो फ्लोट या डबल अंक खोने के बिना पकड़ सकते हैं (फ्लोट के लिए 23 बिट्स, डबल के लिए 53 बिट्स), तो आपकी विधि बेहतर हो सकती है (मान लीजिए कि कोई नहीं है पूर्णांक गणित में अतिप्रवाह)।
उन सभी के शीर्ष पर, क्योंकि पहले फॉर्म का उपयोग "हर किसी" द्वारा किया जाता है, यह वह है जिसे संकलक पहचानता है और अनुकूलित कर सकता है।
जाहिर है, परिणाम दोनों संकलक इस्तेमाल किया जा रहा है और प्रोसेसर पर चलता है यह इस पर निर्भर है, लेकिन इन कोड ऊपर पोस्ट, clang++
(v3.9-रिलीज के माध्यम से संकलित चलने से मेरे परिणाम, सुंदर जारी किया गया के करीब हैं 3.8)।
round_divide_by_float_casting(): 32.5 ns
round_divide_by_modulo(): 113 ns
divide_by_quotient_comparison(): 80.4 ns
हालांकि, दिलचस्प बात यह है मुझे लगता है कि जब मैं उत्पन्न कोड को देखो:
xorps %xmm0, %xmm0
cvtsi2ssl 8016(%rsp,%rbp), %xmm0
xorps %xmm1, %xmm1
cvtsi2ssl 4016(%rsp,%rbp), %xmm1
divss %xmm1, %xmm0
callq roundf
cvttss2si %xmm0, %eax
movl %eax, 16(%rsp,%rbp)
addq $4, %rbp
cmpq $4000, %rbp # imm = 0xFA0
jne .LBB0_7
कि round
वास्तव में एक फोन है। जो वास्तव में मुझे आश्चर्यचकित करता है, लेकिन बताता है कि कुछ मशीनों (विशेष रूप से अधिक हालिया x86 प्रोसेसर) पर, यह तेज़ है।
g++
-ffast-math
साथ बेहतर परिणाम है, जो चारों ओर देता है देता है:
round_divide_by_float_casting(): 17.6 ns
round_divide_by_modulo(): 43.1 ns
divide_by_quotient_comparison(): 18.5 ns
(यह 100k मूल्यों की वृद्धि हुई गिनती के साथ है)
मेरे लिए पहला सबसे स्पष्ट है। मुझे पता है कि यह करने की कोशिश कर रहा है। मुझे पता है कि यह कैसे करने की कोशिश कर रहा है। कागज पर हालांकि इसे चलाने के बिना मुझे नहीं पता कि दूसरा क्या कर रहा है। मैं भी पहले टिपिंग कर रहा हूं क्योंकि दूसरा अंक कई अंकगणितीय परिचालन करता है – John3136
मैं सहमत हूं कि स्पष्टता महत्वपूर्ण है। लेकिन ऑपरेशन जटिलता (और गति) के लिए, मुझे यकीन नहीं है। –