2014-04-14 3 views
5

निम्नलिखित कार्यक्रम में, लाइनdefclass प्रकार की जानकारी

(declare (type (simple-array bit) arr)) 

को हटाने के 3 के एक से अधिक कारक द्वारा समय वृद्धि चल रहा है, SBCL का उपयोग कर बनाता है। दूसरी ओर :type के माध्यम से defclass मैक्रो में दी गई प्रकार की जानकारी प्रदर्शन पर कोई प्रभाव नहीं पड़ती है।

(defclass class-1() ((arr :type (simple-array bit)))) 

(defun sample (inst) 
    (declare (type class-1 inst)) 
    (let ((arr (slot-value inst 'arr))) 
    (declare (type (simple-array bit) arr)) ;; 3x running time without 
    (map-into arr #'(lambda (dummy) (if (< (random 1.0) 0.5) 0 1)) arr))) 

(let ((inst (make-instance 'class-1))) 
    (setf (slot-value inst 'arr) (make-array 10000 :element-type 'bit)) 
    (loop for i from 1 to 10000 do (sample inst))) 

कैसे मैं हर बार जब मैं इसका इस्तेमाल arr स्लॉट एक simple-array bit घोषित करने के लिए बिना एक ही प्रदर्शन लाभ हो सकता है? उत्तरार्द्ध विशेष रूप से कष्टप्रद है (जहां तक ​​मुझे पता चला है) को let या प्रत्येक बार इसी तरह के बाध्यकारी पेश करने की आवश्यकता है; मैं उस स्थान पर केवल (slot-value inst 'arr) लिख नहीं सकता जहां मुझे इसकी आवश्यकता है।

उत्तर

5

सबसे पहले, यह एक एसबीसीएल-विशिष्ट प्रश्न है, आपको एसबीसीएल उपयोगकर्ता सूची पर बेहतर उत्तर मिल सकता है। विभिन्न कंपाइलर्स अलग-अलग अनुकूलन करते हैं, और कम से कम कुछ घोषणाओं को अनदेखा करते हैं।

दूसरा, आपको arr को दोबारा बांधना चाहिए क्योंकि आप इसे दो बार उपयोग कर रहे हैं।

(the (simple-array bit) (slot-value inst 'arr)) 

चौथा, यदि आप प्रकार अनुमान लगाने के लिए संकलक चाहते हैं, एक विशिष्ट पाठक बजाय slot-value का उपयोग करें:

तीसरा, आप the अगर आप जाने-बाँध से बचना चाहते हैं का उपयोग कर सकते हैं:

(defclass c() ((arr :type (simple-array bit) :reader c-arr))) 

(defun sample (inst) 
    (declare (type class-1 inst)) 
    (let ((arr (c-arr inst))) 
    (map-into arr #'(lambda (dummy) (random 2)) arr))) 

c-arr (के रूप में आप अपने आप को पता चला है!) संकलक मान प्रकार आसान अनुमान लगाने के लिए अनुमति चाहिए, लेकिन आप की आवश्यकता हो सकती इसके रिटर्न प्रकार की घोषणा करने के लिए:

(declaim (ftype (function (c) (simple-array bit)) c-arr)) 

कारण यह है कि एसबीसीएल स्लॉट प्रकार की घोषणाओं को अनदेखा करता है।

+0

एक पाठक का उपयोग करना एक अच्छा विचार था, लेकिन यह मेरे लिए सीधे काम नहीं करता था। हालांकि, आपके वर्ग और फ़ंक्शन नामों का उपयोग करके, एक पाठक प्लस निम्नलिखित है: '(अस्वीकरण (ftype (फ़ंक्शन ((सी)) (सरल-सरणी बिट)) सी-एआर))'। इस जगह के साथ, यहां तक ​​कि ': type' को छोड़ा जा सकता है, साथ ही' (घोषित करें (टाइप क्लास -1 इंस्ट)) '। –

+0

यह शायद 'होना चाहिए (अस्वीकरण (ftype (फ़ंक्शन (सी) (सरल-सरणी बिट)) सी-एआर))'। दोनों काम पर दिखाई देते हैं, मुझे यकीन नहीं है कि क्यों। पहले उस फॉर्म का उपयोग नहीं किया है। –

4

प्रकार की जानकारी जोड़ने से अलग-अलग प्रभाव पड़ते हैं कि आप किस कंपाइलर का उपयोग करते हैं और कौन सा अनुकूलन स्तर प्रभावी है।

एक अनुकूलन संकलक यह ऐसा दिख सकता है के लिए:

  • कोई जानकारी नहीं: सामान्य संचालन, यथोचित तेज
  • प्रकार घोषणा उपलब्ध: जोड़ा संचालन रनटाइम के दौरान इस विशेष प्रकार के लिए जाँच करने के लिए -> धीमी
  • उपलब्ध घोषणाएं, उच्च अनुकूलन और कम सुरक्षा: रनटाइम पर चेक टाइप करने के लिए कोई अतिरिक्त ऑपरेशन नहीं, इस प्रकार के लिए जेनरेट किया गया विशेष कोड -> संभावित रूप से तेज

कुछ कंपाइलर CLOS स्लॉट के लिए प्रकार की घोषणाओं को भी अनदेखा करते हैं। यदि वे नहीं करते हैं, तो दो प्रकार हैं: 1) सुरक्षा का मतलब रनटाइम चेक जोड़ा गया है और 2) कम सुरक्षा और उच्च गति का मतलब है विशेष निर्देश उत्पन्न

सारांश: प्रकार की घोषणा अतिरिक्त प्रकार के कारण उच्च सुरक्षा के साथ रनटाइम ओवरहेड जोड़ सकती है जाँच करता है। कम सुरक्षा और उच्च अनुकूलन के साथ विशेष डेटा प्रकार जरूरी नहीं है।

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