2010-12-19 14 views
12

मुझे वास्तव में लुआ में एक पूर्णांक प्रकार होना चाहिए।लुआ इंटीजर प्रकार

पूर्णांक प्रकार का मेरा मतलब सामान्य ऑपरेटरों (/ * + आदि) को परिभाषित करने और एक पूर्णांक की तरह व्यवहार करने का एक प्रकार है, आंतरिक प्रतिनिधित्व कोई फर्क नहीं पड़ता।

टेबल के साथ ऐसी चीज करना बहुत आसान है, समस्या यह है कि मैंने कोशिश की, और प्रदर्शन बहुत खराब है (बेशक)। यहां मेरा आंशिक कार्यान्वयन है:

function num_op(a, b, calc_func) 
    local atype = pytype(a) 
    local btype = pytype(b) 
    local a_val, b_val 

    a_val = (atype == "Integer" or atype == "Double") and a[1] or a 
    b_val = (btype == "Integer" or btype == "Double") and b[1] or b 
    val = calc_func(a_val, b_val) 

    if atype == "Integer" and btype == "Integer" then 
     return Integer:create(val) 
    else 
     return Double:create(val) 
    end 
end 

numeric_mt = { 
    __add = function(a, b) 
     return num_op(a, b, function(a,b) return a + b end) 
    end, 

    __sub = function(a, b) 
     return num_op(a, b, function(a,b) return a - b end) 
    end, 

    __div = function(a, b) 
     return num_op(a, b, function(a,b) return a/b end) 
    end, 

    __mul = function(a, b) 
     return num_op(a, b, function(a,b) return a * b end) 
    end, 

    __tostring = function(a) 
     return tostring(a[1]) 
    end 
} 

----------------------------- 
-- Integer type definition -- 
----------------------------- 

Integer = {} 
Integer_mt = table.copy(numeric_mt) 
Integer_mt["__index"] = Integer 

function Integer:create(value) 
    local new_inst = {math.floor(value)} 
    setmetatable(new_inst, Integer_mt) 
    return new_inst 
end 

function Integer:className() 
    return "Integer" 
end 

जो मैं इकट्ठा करता हूं उससे मुख्य प्रदर्शन जुर्माना (बेशक) बहुत सारे आवंटन है। लुआजिट ऑपरेटरों के कार्यों को काफी अच्छी तरह अनुकूलित करने में सक्षम है, लेकिन मेटाटेबल्स आवंटन नहीं।

क्या कोई सोचता है कि एक कस्टम सी कार्यान्वयन और उपयोगकर्ता डेटा के साथ बेहतर करना संभव होगा? या क्या मैं हासिल करने के लिए असंभव पीछा कर रहा हूँ?

एनबी: i पता लुआ में पूर्णांक नहीं हैं। मुझे यह भी पता है कि मैं गणित lib का उपयोग कर एक ही परिणाम प्राप्त कर सकता हूं। मैं चाहता हूं कि निर्माण चरण को छोड़कर, पूर्णांक का उपयोग करते समय पूर्ण पारदर्शिता पूर्ण हो।

संपादित करें: मैं यहाँ में अतिरिक्त जानकारी जोड़ने कर रहा हूँ ताकि सब कुछ अभी भी केंद्रीकृत

@Mud है: मैं की जरूरत है, एक निश्चित सीमा तक उसी तरह आप अजगर में है में पारदर्शी मिश्रित arithmetics के लिए/रूबी/आदि, लेकिन सर्वोत्तम प्रदर्शन के साथ संभव है। मैं luaJIT का उपयोग एक कंपाइलर के लिए एक लक्ष्य के रूप में कर रहा हूं, जिसमें नियमित लुआ प्लेटफार्मों के लिए फॉलबैक के रूप में लुआजिट द्वारा समर्थित नहीं है। प्रदर्शन विशेषताओं के लिए यह बहुत महत्वपूर्ण है।

इसका मतलब है कि मैं यह करने के लिए सक्षम होने के लिए करना चाहते हैं:

a = int(5) -- Integer value 
b = int(2) -- Another Integer 
c = 2  -- Double 
d = a/b -- == 2 , integer arithmetics 
e = a/c -- == 2.5, floating point arithmetics 

मैं, एक निश्चित बिंदु तक पहुँच सकते हैं कि कार्यान्वयन के साथ ऊपर से पता चला है। समस्या यह है कि मैं हर संख्या पर संचालन धीमा कर रहा हूं, क्योंकि नियमित संख्याओं को भी बॉक्स किया जाता है। मैं डिबग lib साथ संख्याओं की metatable ओवरलोड सकता है, लेकिन

  • मैं नहीं जानता कि कैसे विश्वसनीय इस सुविधा के लिए, उत्पादन गुणवत्ता सॉफ्टवेयर में उपयोग
  • यह अभी भी के बाद से संख्या के प्रदर्शन धीमी हो जाएगी के लिए है संख्याओं के लिए एक एकीकृत इंटरफ़ेस प्राप्त करने में सक्षम होने के लिए, मुझे (संख्या) का उपयोग करना होगा: get(), जो किसी भी मामले में ऑपरेशन धीमा कर देगा।

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

एक और समाधान हमेशा अनबॉक्स किए गए नंबरों का उपयोग करना होगा, और पूर्णांक को ट्रैक करने के लिए मेरे कंपाइलर में किसी प्रकार के प्रकार का प्रचार करना होगा और आवश्यकता होने पर उचित इनलाइन संचालन का उपयोग करना होगा, लेकिन इस समाधान की जटिलता बहुत बड़ी है, और दयालु लूआ/लुआजिट का बैकएंड के रूप में उपयोग करने के पूरे उद्देश्य को हरा देता है।

मैं आपके कार्यान्वयन की कोशिश कर रहा हूं, लेकिन मुझे संदेह है कि यह लुआजिट में इनलाइन कॉल से बेहतर होगा।यह बहुत अच्छा हो सकता है कि मैं किसके लिए शूटिंग कर रहा हूं (डबल और पूर्णांक दोनों पारदर्शी संचालन, और लुआजिट पर इनलाइन कॉल के करीब प्रदर्शन) सादा असंभव है। आपकी मदद के लिए बहुत बहुत शुक्रिया।

@ मिकी: धन्यवाद, यह अच्छा लग रहा है, लेकिन मुझे संदेह है कि मैं इसके साथ लुजिट पैच कर सकता हूं, और यदि मैं नहीं कर सकता, तो यह मेरे लक्ष्य के लिए अपनी सभी अंतःक्रिया को खो देता है।

+2

हाँ, कि, सच है कुछ भी साथ LuaJIT पैच करने के लिए कोशिश कर रहा पागलपन है, यह हमेशा शुद्ध लुआ में पूरी बात को लागू करने के लिए बेहतर है (अच्छी तरह से, कि क्या लुआ के लिए अच्छा है यह उपकरण प्रदान करता है, .. ।)। फिर लुआजिट इसे अनुकूलित करने में सक्षम होगा (सी कार्यों के साथ नहीं)। –

उत्तर

4

आप करने के लिए आप कर सकते थे #define LUA_NUMBER intluaconf.h में हमेशा पूर्णांकों के साथ ही सौदा चाहते हैं।

14

क्यों क्या आपको उनकी आवश्यकता है? आपकी समस्या का एक निष्पादक समाधान खोजने में आपकी सहायता करने का सबसे अच्छा तरीका समस्या को समझना है। विशेष रूप से आपको पूर्णांक की आवश्यकता क्या है?

जो मैं इकट्ठा करता हूं उससे मुख्य प्रदर्शन जुर्माना (बेशक) बहुत सारे आवंटन है।

ठीक है, आप हर ऑपरेशन पर बंद कर रहे हैं, और मुझे समझ में नहीं आता कि आपके पास डबल क्लास क्यों है, यह देखते हुए कि लुआ का नंबर पहले से ही एक डबल है। क्या आप ऐसा कुछ नहीं कर सके?

Integer = {} 
local function val(o) return type(o) == 'number' and o or o[1] end 
function Integer.__add(a,b) return Integer:create(val(a) + val(b)) end 
function Integer.__sub(a,b) return Integer:create(val(a) - val(b)) end 
function Integer.__div(a,b) return Integer:create(val(a)/val(b)) end 
function Integer.__mul(a,b) return Integer:create(val(a) * val(b)) end 
function Integer:__tostring() return tostring(self[1]) end 
function Integer:create(value) 
    return setmetatable({math.floor(value)}, Integer) 
end 


-- test 
a = Integer:create(15.34) 
b = Integer:create(775.34433) 
print((a*10/2+b-3)/3*a+b) --> 5005 

किसी लगता है कि यह एक कस्टम ग कार्यान्वयन और userdata के साथ बेहतर करना संभव हो सकता है?

हां, एक सी कार्यान्वयन तेज़ होना चाहिए, क्योंकि आपको प्रत्येक इंटीजर के लिए एक टेबल बनाने की आवश्यकता नहीं होगी; आपका उपयोगकर्ता डेटा सचमुच सिर्फ int* हो सकता है। यह floor कॉल की आवश्यकता को भी समाप्त कर देगा।

संपादित करें: मैंने test C implementation लिखा है और यह इस पोस्ट में प्रस्तुत लुआ कार्यान्वयन से ~ 5 गुना तेज है।

+0

अरे मिड, आपके उत्तर के लिए धन्यवाद, मैंने मूल प्रश्न –

+1

में जवाब दिया, मैंने आपका जवाब स्वीकार कर लिया, क्योंकि अगर यह अंत में मेरी समस्या का समाधान नहीं करता है, तो यह * प्रश्न का उत्तर देता है। हालांकि सी पुस्तकालयों का उपयोग करते समय लुआजिट दुभाषिया को गिरता है, इसलिए सी पुस्तकालय का उपयोग अंत –

1

आप LNUM पैच को आजमा सकते हैं, यह लूआ कोर को पूर्णांक संख्यात्मक प्रकारों को जोड़ने के लिए संशोधित करता है, जैसे 32 और 64 बिट पूर्णांक युगल के साथ। यह जटिल संख्या का भी समर्थन करता है।

+0

में एक अच्छा समाधान नहीं था रीडमे से: "पैच का उपयोग किसी भी तरह से लुआ बाहरी व्यवहार को नहीं बदलता है"। तो निश्चित रूप से नहीं कि मैं क्या कर रहा हूँ –

2

आप http://www.tecgraf.puc-rio.br/~lhf/ftp/lua/ पर सूचीबद्ध मनमाने ढंग से सटीक पुस्तकालयों में से एक को आजमा सकते हैं। विशेष रूप से, lbn पूर्णांक केवल और तेज़ है लेकिन आपको OpenSSL की आवश्यकता है। एक साधारण स्व-निहित पुस्तकालय के लिए, lbc देखें।