2013-04-26 8 views
6

मुझे मिश्रित प्रकार - स्ट्रिंग्स और युगल के टैब्यूलर डेटा की बड़ी मात्रा में संसाधित करने की आवश्यकता है। एक मानक समस्या, मुझे लगता है। Matlab में इस के साथ काम करने के लिए सबसे अच्छी डेटा संरचना क्या है?मैटलैब डेटा संरचना - समय क्या है + अंतरिक्ष कुशल?

सेलरेरे निश्चित रूप से उत्तर नहीं है। यह अत्यंत स्मृति अक्षम है। (नीचे दिखाए गए परीक्षण)। डेटासेट (आंकड़े टूलबॉक्स से) बहुत समय और अंतरिक्ष अक्षम है। यह मुझे संरचनाओं या सरणी की संरचना के साथ छोड़ देता है। मैंने नीचे दिए गए समय और स्मृति दोनों के लिए चार अलग-अलग विकल्पों में एक परीक्षण किया और ऐसा लगता है कि मेरे द्वारा परीक्षण की जाने वाली चीज़ों के लिए सरणी की संरचना सबसे अच्छा विकल्प है।

मैं मैटलैब के लिए अपेक्षाकृत नया हूं और यह थोड़ा निराशाजनक है। वैसे भी - इस बारे में सलाह की तलाश है कि मुझे कुछ याद आ रहा है, या यदि मेरे परीक्षण सटीक/उचित हैं। क्या मैं एक्सेस/रूपांतरण/मेमोरी उपयोग के अलावा अन्य विचारों को याद कर रहा हूं, जो इस सामग्री का उपयोग करके कोड को और अधिक होने की संभावना है। (fyi R2010b का उपयोग कर रहा हूँ)

* * टेस्ट # 1: एक्सेस गति डेटा आइटम तक पहुंच।

cellarray:0.002s 
dataset:36.665s  %<<< This is horrible 
structarray:0.001s 
struct of array:0.000s 

* * टेस्ट # 2: रूपांतरण की गति और स्मृति के उपयोग मैं इस परीक्षण से डाटासेट गिरा दिया।

Cellarray(doubles)->matrix:d->m: 0.865s 
Cellarray(mixed)->structarray:c->sc: 0.268s 
Cellarray(doubles)->structarray:d->sd: 0.430s 
Cellarray(mixed)->struct of arrays:c->sac: 0.361s 
Cellarray(doubles)->struct of arrays:d->sad: 0.887s 
    Name   Size    Bytes Class  Attributes 
    c   100000x10   68000000 cell     
    d   100000x10   68000000 cell     
    m   100000x10    8000000 double    
    sac   1x1    38001240 struct    
    sad   1x1    8001240 struct    
    sc  100000x1    68000640 struct    
    sd  100000x1    68000640 struct 

================== कोड: जांच # 1

%% cellarray 
    c = cell(100000,10); 
    c(:,[1,3,5,7,9]) = num2cell(zeros(100000,5)); 
    c(:,[2,4,6,8,10]) = repmat({'asdf'}, 100000, 5); 
    cols = strcat('Var', strtrim(cellstr(num2str((1:10)'))))'; 
    te = tic; 
    for iii=1:1000 
     x = c(1234,5); 
    end 
    te = toc(te); 
    fprintf('cellarray:%0.3fs\n', te); 
    %% dataset 
    ds = dataset({ c, cols{:} }); 
    te = tic; 
    for iii=1:1000 
     x = ds(1234,5); 
    end 
    te = toc(te); 
    fprintf('dataset:%0.3fs\n', te); 
    %% structarray 
    s = cell2struct(c, cols, 2); 
    te = tic; 
    for iii=1:1000 
     x = s(1234).Var5; 
    end 
    te = toc(te); 
    fprintf('structarray:%0.3fs\n', te); 
    %% struct of arrays 
    for iii=1:numel(cols) 
     if iii/2==floor(iii/2) % even => string 
      sac.(cols{iii}) = c(:,iii); 
     else 
      sac.(cols{iii}) = cell2mat(c(:,iii)); 
     end 
    end 
    te = tic; 
    for iii=1:1000 
     x = sac.Var5(1234); 
    end 
    te = toc(te); 
    fprintf('struct of array:%0.3fs\n', te); 

============= ===== कोड: जांच # 2

%% cellarray 
% c - cellarray containing mixed type 
c = cell(100000,10); 
c(:,[1,3,5,7,9]) = num2cell(zeros(100000,5)); 
c(:,[2,4,6,8,10]) = repmat({'asdf'}, 100000, 5); 
cols = strcat('Var', strtrim(cellstr(num2str((1:10)'))))'; 
% c - cellarray containing doubles only 
d = num2cell(zeros(100000, 10)); 
%% matrix 
% doubles only 
te = tic; 
m = cell2mat(d); 
te = toc(te); 
fprintf('Cellarray(doubles)->matrix:d->m: %0.3fs\n', te); 
%% structarray 
% mixed 
te = tic; 
sc = cell2struct(c, cols, 2); 
te = toc(te); 
fprintf('Cellarray(mixed)->structarray:c->sc: %0.3fs\n', te); 
% doubles 
te = tic; 
sd = cell2struct(d, cols, 2); 
te = toc(te); 
fprintf('Cellarray(doubles)->structarray:d->sd: %0.3fs\n', te); 
%% struct of arrays 
% mixed 
te = tic; 
for iii=1:numel(cols) 
    if iii/2==floor(iii/2) % even => string 
     sac.(cols{iii}) = c(:,iii); 
    else 
     sac.(cols{iii}) = cell2mat(c(:,iii)); 
    end 
end 
te = toc(te); 
fprintf('Cellarray(mixed)->struct of arrays:c->sac: %0.3fs\n', te); 
% doubles 
te = tic; 
for iii=1:numel(cols) 
    sad.(cols{iii}) = cell2mat(d(:,iii)); 
end 
te = toc(te); 
fprintf('Cellarray(doubles)->struct of arrays:d->sad: %0.3fs\n', te); 
%% 
clear iii cols te; 
whos 
+0

जबकि 'डेटासेट' वास्तव में धीमा है, आपका समय बहुत धीमा है। मैं डेटासेट प्राप्त कर रहा हूं: पहुंच पर 0.7 एस 'जबकि अन्य आपके जैसा ही क्रम में हैं। मैं 32-बिट WinXP – Amro

उत्तर

1

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

हालांकि, अगर आप MATLAB इस्तेमाल की योजना बना रहे हैं वैसे भी मैं अभी भी cellarrays का चयन करेंगे, कि अगर आप fieldnamesसंरचनाओं में के रूप में के रूप में अपने डेटा को वाक्यात्मक संदर्भ की आवश्यकता नहीं है।

सेलराय का उपयोग करते समय, ध्यान रखें कि प्रत्येक सेल 112 बाइट ओवरहेड लगाता है।

c = cell(1,10); 
c(1,1:2:10) = num2cell(rand(1e5,5),1); 
c(1,2:2:10) = {cellstr(repmat('asdf', 100000, 1))}; 

और स्मृति-वार (समय में कोई बदलाव नहीं):

Name   Size    Bytes Class Attributes 
c    1x10   38000600 cell 

इसके अलावा, आप क्या कहते हैं इसलिए, मैं प्रत्येक स्तंभ (न कि प्रत्येक अदिश डबल के लिए एक सेल) के लिए एक सेल बनाना होगा सरणी की एक संरचना को आमतौर पर 'स्केलर' संरचना के साथ संदर्भित किया जाता है क्योंकि संरचना सरणी (या गैर-स्केलर संरचना) के विपरीत होता है।

यदि मुझे सही ढंग से याद किया जाता है, तो जब आप घोंसले के खेतों को शुरू करते हैं तो मुझे पढ़ने/लिखने के लिए प्रदर्शन में गिरावट आती है (हालांकि मुझे विशिष्ट धागा ढूंढना होगा)।

3

मैटलैब कोड स्थान बनाने का तरीका- और समय-कुशल प्राइमेटिव के बड़े सरणी के साथ काम करना है - यानी, युगल, स्याही, या वर्णों के सरणी। यह आपको स्मृति में एक कठिन लेआउट देता है और आपको वेक्टरीकृत ऑपरेशन करने देता है।

टैब्यूलर डेटा के लिए, प्रत्येक कॉलम प्रकार में समरूप होता जा रहा है, लेकिन अलग-अलग कॉलम विभिन्न प्रकार के हो सकते हैं, और आपके पास आमतौर पर कॉलम की तुलना में बहुत अधिक पंक्तियां होंगी। और आप प्रायः ऑपरेशन कर रहे होंगे - तुलना या गणित - कॉलम के सभी तत्वों पर, या कॉलम का मुखौटा चयन, जो स्वयं को वेक्टरकृत ऑपरेशंस में उधार देता है। इसलिए प्राइमेटिव्स की आशा है कि प्रत्येक कॉलम को कॉलम सरणी के रूप में स्टोर करें। आप उन कॉलम को या तो सेल वेक्टर के स्ट्रक्चर या तत्वों के क्षेत्र में चिपका सकते हैं; इससे ज्यादा प्रदर्शन नहीं होता है, और संरचना का फॉर्म अधिक पठनीय होगा और एक टेबल की तरह दिखता है। एक 2-डी सेल सरणी या अन्य डेटा संरचना जो सभी तत्वों को अपने छोटे mxarrays में विभाजित करती है वह accepatbly प्रदर्शन नहीं करने जा रही है।

यह है कि, यदि आपके पास 10 कॉलम तालिका द्वारा 10,000 पंक्ति है, तो आप 10-लंबे सेल सरणी या 10-फ़ील्ड स्ट्रक्चर रखना चाहते हैं, जिनमें से प्रत्येक फ़ील्ड या 10,000-वर्षीय आदिम कॉलम वेक्टर वाले तत्व हैं।

dataset ऑब्जेक्ट ऑब्जेक्ट मूल रूप से किसी ऑब्जेक्ट में फंस गए पहले वर्णित कॉलम सरणी की संरचना के चारों ओर एक रैपर होता है। लेकिन नियमित रूप से structs और कोशिकाओं की तुलना में Matlab में वस्तुओं अधिक overhead है; आप प्रत्येक एक्सेस पर एक या अधिक विधि कॉल के लिए भुगतान कर रहे हैं। Is MATLAB OOP slow or am I doing something wrong? पर एक नज़र डालें (पूर्ण प्रकटीकरण: यह मेरे उत्तरों में से एक है)।

आपके द्वारा सेट किया गया परीक्षण यह इंगित नहीं करता है कि मैटलैब कोड कितना अच्छा प्रदर्शन करेगा, क्योंकि यह स्केलर सिंगल-एलिमेंट एक्सेस कर रहा है। यही है, यह कॉलम के लिए भुगतान कर रहा है और फिर लूप के माध्यम से प्रत्येक पास पर पंक्ति तत्व का उपयोग कर रहा है। यदि आपका मैटलैब कोड ऐसा कर रहा है, तो आप पहले ही भाग्य से बाहर हैं। तेजी से होने के लिए, आपको लूप के बाहर कॉलम पॉप आउट करने की आवश्यकता है - यानी, बाहरी लूप या सेटअप कोड पर महंगे कॉलम एक्सेस ऑपरेशन को बढ़ाएं - और फिर या तो वेक्टरीकृत ऑपरेशंस (जैसे +, ==, '<', ismember, और इसी तरह) पूरे कॉलम वैक्टर, या आदिम न्यूमेरिक वैक्टर (जो कि जेआईटी अनुकूलित कर सकते हैं) पर लूप पर। यदि आप ऐसा करते हैं, तो dataset और अन्य ऑब्जेक्ट-आधारित टैब्यूलर संरचनाओं में सभ्य प्रदर्शन हो सकता है।

मैटलैब में स्ट्रिंग्स, चूसने की तरह, दुर्भाग्य से। आप सेलस्टर्स से दूर जाना चाहते हैं। आपके पास कुछ विकल्प हैं।

  • एक कॉलम में तार एक ही लंबाई के बारे में कर रहे हैं, और आप उन्हें किसी भी लंबे तार की जरूरत नहीं है, तो आप एक 2-डी char सरणी के रूप में तार का एक वेक्टर स्टोर कर सकते हैं। यह स्मृति में एक एकल संगत सरणी है और एक सेल सरणी से अधिक अंतरिक्ष-कुशल है, और तुलना संचालन के लिए और अधिक तेज़ हो सकता है। यह मैटलैब के देशी स्ट्रिंग प्रस्तुतियों में से एक है, इसलिए सामान्य स्ट्रिंग फ़ंक्शन इसके साथ काम करेंगे।
  • यदि स्ट्रिंग कम कार्डिनालिटी हैं (यानी, अलग-अलग मानों की संख्या तत्वों की कुल संख्या के सापेक्ष छोटी है), तो आप उन्हें "प्रतीकों" के रूप में एन्कोड कर सकते हैं, उन्हें आदिम इंक की एक सरणी के रूप में संग्रहीत कर सकते हैं जो इंडेक्स में हैं विशिष्ट स्ट्रिंग मानों की एक सूची में। unique और ismember फ़ंक्शन इन एन्कोडिंग को लागू करने में सहायता कर सकता है। जब तक आप केवल समानता परीक्षण कर रहे हैं और सॉर्ट नहीं कर रहे हैं, तब तक ये एन्कोडेड स्ट्रिंग कॉलम संख्यात्मक गति से संचालित होंगे।
  • मैं Toolboxes में से एक का मानना ​​है, हो सकता है dataset के साथ एक, "वर्गीकारक" या "स्पष्ट" चर, जो मूल रूप से है कि कम प्रमुखता एन्कोडिंग की एक रेडीमेड कार्यान्वयन कर रहे हैं के लिए समर्थन हासिल है।
  • जावा स्ट्रिंग्स से परेशान न करें; Matlab-to-Java बाधा को पार करने में ओवरहेड इसे शुद्ध नुकसान पहुंचाएगा।
  • उम्मीद है कि अब तक कोई और कुछ लेकर आया है।

आप, cellstrs साथ चिपके रहते हैं जैसा कि ऊपर वर्णित उन्हें संरचना के भीतर cellstr स्तंभ वैक्टर के रूप में स्टोर करने के लिए है, तो; जब आप वास्तव में स्ट्रिंग कॉलम पर काम कर रहे हों तो आपको केवल सेल एक्सेस की कीमत का भुगतान करना होगा।

+0

+1 पर R2013a चला रहा हूं अच्छी तरह से समझाया गया और अंतर्दृष्टिपूर्ण उत्तर। इसके अलावा ओओपी ओवरहेड मुद्दे ने प्रदर्शन-वार में निश्चित रूप से सुधार किया है। उदाहरण के लिए मुझे केवल इस परीक्षा में (डेटा2013 में) 'डेटासेट' पहुंच के लिए 0.7 मिल रहा है, बनाम 36 सेकेंड ओपी ने – Amro

+0

की सूचना दी है बेशक अभी भी सुधार के लिए जगह है। यह दिलचस्प होगा यदि आप अपने बेंचमार्क परिणामों को अपडेट कर सकते हैं यदि आपके पास नवीनतम संस्करण – Amro

+0

धन्यवाद है। हाँ, एक अच्छा विचार की तरह ध्वनि उन्नयन। गैर-ओओपी प्रदर्शन भी सुधारना चाहिए। डर है कि किसी और को एक अद्यतन बेंचमार्क करना होगा, हालांकि - मैंने नौकरियां बदल दी हैं और इस समय मैटलैब लाइसेंस नहीं है। –

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