दिलचस्प पोस्ट
रेजर एक्शनलिंक autogenerating? लंबाई = 7 यूआरएल में? डेस्कटॉप और मोबाइल दृश्यों के लिए वस्तुओं को पुन: व्यवस्थित करने के लिए फ्लेक्स ऑर्डर की सुविधा का उपयोग करना जांचने का बेहतर तरीका है कि क्या पथ फ़ाइल या निर्देशिका है? क्या वस्तु संदर्भ संख्या प्राप्त करना संभव है? "स्थान की आवश्यकता है" अपवाद लोड करते समय FXML फ़ाइल विजुअल स्टूडियो 2012 वेब प्रकाशित फाइल कॉपी नहीं करता है फ़ंक्शन के अंदर स्थानीय रूप से एक एक्सटर्न वैरिएबल को आरंभ करने में त्रुटि क्यों होती है? मैं .NET में एक कॉम्बो बॉक्स गैर-संपादन योग्य कैसे बना सकता हूं? आरएसपीसी का उपयोग कब करें ()? स्थिर तरीके धागे सुरक्षित हैं ASP.NET वेबफॉर्म के साथ AJAX के लिए jQuery का उपयोग करना JavaScript में `नया` क्या करता है, वैसे भी? अलर्ट या कन्फर्म बॉक्स में टेक्स्ट बोल्ड कैसे प्राप्त करें? एंड्रॉइड वेबव्यू में कीबोर्ड के नीचे छिपा हुआ टेक्स्टबॉक्स REST जर्सी में अपवाद

सबसे तेज़ Matlab फाइल पढ़ने?

मेरा MATLAB कार्यक्रम 7 मीटर लाइनों के बारे में एक फाइल पढ़ रहा है और I / O पर बहुत ज्यादा समय बर्बाद कर रहा है मुझे पता है कि प्रत्येक पंक्ति को दो पूर्णांक के रूप में स्वरूपित किया गया है, लेकिन मुझे नहीं पता कि वह कितने अक्षर लेते हैं। str2num घातक धीमा है, क्या बजाय मुझे matlab फ़ंक्शन का उपयोग करना चाहिए?

पकड़ो: मुझे पूरी फ़ाइल मेमोरी को संग्रहीत किए बिना एक समय में प्रत्येक पंक्ति पर काम करना पड़ता है, इसलिए पूरे मैट्रिक्स को पढ़ने वाले आदेशों में से कोई भी मेज पर नहीं है

fid = fopen('file.txt'); tline = fgetl(fid); while ischar(tline) nums = str2num(tline); %do stuff with nums tline = fgetl(fid); end fclose(fid); 

Solutions Collecting From Web of "सबसे तेज़ Matlab फाइल पढ़ने?"

समस्या का विवरण

यह एक आम संघर्ष है, और उत्तर देने के लिए एक परीक्षा की तरह कुछ भी नहीं है। ये मेरी मान्यताओं हैं:

  1. एक अच्छी तरह से स्वरूपित एएससीआईआई फ़ाइल, जिसमें संख्याओं के दो स्तंभ हैं। कोई हेडर नहीं, कोई असंगत लाइन नहीं आदि

  2. मेमोरी में शामिल होने वाली फ़ाइलों को पढ़ने के लिए विधि को बड़े पैमाने पर होना चाहिए (हालांकि मेरा धैर्य सीमित है, इसलिए मेरी परीक्षा फ़ाइल केवल 500,000 लाइनें है)।

  3. वास्तविक ऑपरेशन (ओपी कॉल "क्या चीज़ों के साथ काम करता है") एक समय में एक पंक्ति को किया जाना चाहिए, वैक्टरयुक्त नहीं किया जा सकता।

विचार-विमर्श

इसे ध्यान में रखते हुए, उत्तर और टिप्पणियां तीन क्षेत्रों में दक्षता को प्रोत्साहित करती हैं:

  • बड़े बैचों में फ़ाइल पढ़ना
  • संख्या रूपांतरण को अधिक कुशलता से (या तो बैचिंग के माध्यम से या बेहतर कार्य का उपयोग करके)
  • वास्तविक प्रसंस्करण को और अधिक कुशल बनाना (जो मैंने ऊपर नियम 3 के माध्यम से अस्वीकार किया है)।

परिणाम

इन विषयों पर 6 भिन्नताओं के घूस की गति (और परिणाम की निरंतरता) का परीक्षण करने के लिए मैंने एक त्वरित स्क्रिप्ट को एक साथ रखा है परिणाम हैं:

  • आरंभिक कोड 68.23 सेकंड 582582 चेक करें
  • प्रति पंक्ति एक बार sscanf का उपयोग करना 27.20 सेकंड 582582 चेक करें
  • बड़े बैचों में fscanf का उपयोग करना 8.93 सेकंड 582582 चेक करें
  • बड़े बैचों में ग्रंथों का उपयोग करना 8.79 सेकंड 582582 चेक करें
  • स्मृति में बड़े बैच पढ़ना, फिर sscanf 8.15 सेकंड 582582 चेक करें
  • एकल लाइनों पर जावा एक लाइन फ़ाइल रीडर और sscanf का उपयोग करना 63.56 सेकंड 582582 चेक करें
  • जावा एकल आइटम टोकन स्कैनर का उपयोग करना 81.19 सेकंड 582582 चेक करें
  • पूरी तरह से व्यवस्थित संचालन (गैर-अनुपालन) 1.02 सेकंड 508680 जांच (नियम 3 का उल्लंघन करती है)

सारांश

मूल समय के आधे से अधिक (68 -> 27 सेकंड) स्ट्रोबनम कॉल में अक्षमताओं के साथ खाया गया था, जिसे sscanf स्विच करके हटाया जा सकता है

शेष समय के दूसरे 2/3 (27 -> 8 सेकंड) के बारे में, फ़ाइल रूपांतरण और संख्या रूपांतरणों के लिए स्ट्रिंग दोनों के लिए बड़े बैचों का उपयोग करके कम किया जा सकता है।

यदि हम मूल पद में नियम नंबर तीन का उल्लंघन करने को तैयार हैं, तो समय की एक और 7/8 पूरी तरह से संख्यात्मक प्रसंस्करण पर स्विच करके कम किया जा सकता है हालांकि, कुछ एल्गोरिदम स्वयं को इस पर उधार नहीं देते हैं, इसलिए हम इसे अकेले छोड़ देते हैं। (नहीं "चेक" मान अंतिम प्रविष्टि के लिए मेल नहीं खाता है।)

अंत में, सीधी विरोधाभास में, इस प्रतिक्रिया में मेरा पिछला संपादन, उपलब्ध कैश्ड जावा, सिंगल लाइन रीडर पर स्विच करके कोई भी बचत उपलब्ध नहीं है। वास्तव में यह हल 2 – 3 गुणा देशी पाठकों का उपयोग करके तुलनीय एकल लाइन परिणाम की तुलना में धीमी है। (63 बनाम 27 सेकंड)।

ऊपर वर्णित सभी समाधानों के लिए नमूना कोड नीचे शामिल हैं


नमूना कोड

 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% Create a test file cd(tempdir); fName = 'demo_file.txt'; fid = fopen(fName,'w'); for ixLoop = 1:5 d = randi(1e6, 1e5,2); fprintf(fid, '%d, %d \n',d); end fclose(fid); %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% Initial code CHECK = 0; tic; fid = fopen('demo_file.txt'); tline = fgetl(fid); while ischar(tline) nums = str2num(tline); CHECK = round((CHECK + mean(nums) ) /2); tline = fgetl(fid); end fclose(fid); t = toc; fprintf(1,'Initial code. %3.2f sec. %d check \n', t, CHECK); %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% Using sscanf, once per line CHECK = 0; tic; fid = fopen('demo_file.txt'); tline = fgetl(fid); while ischar(tline) nums = sscanf(tline,'%d, %d'); CHECK = round((CHECK + mean(nums) ) /2); tline = fgetl(fid); end fclose(fid); t = toc; fprintf(1,'Using sscanf, once per line. %3.2f sec. %d check \n', t, CHECK); %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% Using fscanf in large batches CHECK = 0; tic; bufferSize = 1e4; fid = fopen('demo_file.txt'); scannedData = reshape(fscanf(fid, '%d, %d', bufferSize),2,[])' ; while ~isempty(scannedData) for ix = 1:size(scannedData,1) nums = scannedData(ix,:); CHECK = round((CHECK + mean(nums) ) /2); end scannedData = reshape(fscanf(fid, '%d, %d', bufferSize),2,[])' ; end fclose(fid); t = toc; fprintf(1,'Using fscanf in large batches. %3.2f sec. %d check \n', t, CHECK); %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% Using textscan in large batches CHECK = 0; tic; bufferSize = 1e4; fid = fopen('demo_file.txt'); scannedData = textscan(fid, '%d, %d \n', bufferSize) ; while ~isempty(scannedData{1}) for ix = 1:size(scannedData{1},1) nums = [scannedData{1}(ix) scannedData{2}(ix)]; CHECK = round((CHECK + mean(nums) ) /2); end scannedData = textscan(fid, '%d, %d \n', bufferSize) ; end fclose(fid); t = toc; fprintf(1,'Using textscan in large batches. %3.2f sec. %d check \n', t, CHECK); %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% Reading in large batches into memory, incrementing to end-of-line, sscanf CHECK = 0; tic; fid = fopen('demo_file.txt'); bufferSize = 1e4; eol = sprintf('\n'); dataBatch = fread(fid,bufferSize,'uint8=>char')'; dataIncrement = fread(fid,1,'uint8=>char'); while ~isempty(dataIncrement) && (dataIncrement(end) ~= eol) && ~feof(fid) dataIncrement(end+1) = fread(fid,1,'uint8=>char'); %This can be slightly optimized end data = [dataBatch dataIncrement]; while ~isempty(data) scannedData = reshape(sscanf(data,'%d, %d'),2,[])'; for ix = 1:size(scannedData,1) nums = scannedData(ix,:); CHECK = round((CHECK + mean(nums) ) /2); end dataBatch = fread(fid,bufferSize,'uint8=>char')'; dataIncrement = fread(fid,1,'uint8=>char'); while ~isempty(dataIncrement) && (dataIncrement(end) ~= eol) && ~feof(fid) dataIncrement(end+1) = fread(fid,1,'uint8=>char');%This can be slightly optimized end data = [dataBatch dataIncrement]; end fclose(fid); t = toc; fprintf(1,'Reading large batches into memory, then sscanf. %3.2f sec. %d check \n', t, CHECK); %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% Using Java single line readers + sscanf CHECK = 0; tic; bufferSize = 1e4; reader = java.io.LineNumberReader(java.io.FileReader('demo_file.txt'),bufferSize ); tline = char(reader.readLine()); while ~isempty(tline) nums = sscanf(tline,'%d, %d'); CHECK = round((CHECK + mean(nums) ) /2); tline = char(reader.readLine()); end reader.close(); t = toc; fprintf(1,'Using java single line file reader and sscanf on single lines. %3.2f sec. %d check \n', t, CHECK); %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% Using Java scanner for file reading and string conversion CHECK = 0; tic; jFile = java.io.File('demo_file.txt'); scanner = java.util.Scanner(jFile); scanner.useDelimiter('[\s\,\n\r]+'); while scanner.hasNextInt() nums = [scanner.nextInt() scanner.nextInt()]; CHECK = round((CHECK + mean(nums) ) /2); end scanner.close(); t = toc; fprintf(1,'Using java single item token scanner. %3.2f sec. %d check \n', t, CHECK); %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% Reading in large batches into memory, vectorized operations (non-compliant solution) CHECK = 0; tic; fid = fopen('demo_file.txt'); bufferSize = 1e4; eol = sprintf('\n'); dataBatch = fread(fid,bufferSize,'uint8=>char')'; dataIncrement = fread(fid,1,'uint8=>char'); while ~isempty(dataIncrement) && (dataIncrement(end) ~= eol) && ~feof(fid) dataIncrement(end+1) = fread(fid,1,'uint8=>char'); %This can be slightly optimized end data = [dataBatch dataIncrement]; while ~isempty(data) scannedData = reshape(sscanf(data,'%d, %d'),2,[])'; CHECK = round((CHECK + mean(scannedData(:)) ) /2); dataBatch = fread(fid,bufferSize,'uint8=>char')'; dataIncrement = fread(fid,1,'uint8=>char'); while ~isempty(dataIncrement) && (dataIncrement(end) ~= eol) && ~feof(fid) dataIncrement(end+1) = fread(fid,1,'uint8=>char');%This can be slightly optimized end data = [dataBatch dataIncrement]; end fclose(fid); t = toc; fprintf(1,'Fully batched operations. %3.2f sec. %d check \n', t, CHECK); 

(मूल उत्तर)

बेन द्वारा बनाए गए बिंदु पर विस्तार करने के लिए … यदि आप इन फ़ाइलों को लाइन द्वारा लाइन पढ़ रहे हैं तो आपकी बाधा हमेशा I / O फाइल होगी

मैं समझता हूं कि कभी-कभी आप पूरी फ़ाइल को स्मृति में फिट नहीं कर सकते मैं आमतौर पर वर्णों के एक बड़े बैच (1e5, 1e6 या आस-पास, आपके सिस्टम की स्मृति के आधार पर) में पढ़ता हूं। फिर मैं या तो एक राउंड नंबर लाइन प्राप्त करने के लिए अतिरिक्त एकल वर्ण (या एकल वर्णों को वापस) पढ़ता हूं, और फिर अपना स्ट्रिंग पर्सिंग चलाता है (जैसे sscanf)

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

यह थोड़ा थकाऊ है, लेकिन यह मुश्किल नहीं है मैं आमतौर पर एक लाइन पाठकों पर गति में 90% से अधिक सुधार देखता हूं।


(शर्म से हटाए गए जावा बैच लाइन पाठकों का उपयोग करके भयानक विचार)

यहां तक ​​कि अगर आप पूरी फ़ाइल को स्मृति में फिट नहीं कर सकते हैं, तो आपको मैट्रिक्स पठन कार्य का उपयोग करके एक बड़े बैच पढ़ना चाहिए।

हो सकता है कि आप कुछ डेटा प्रोसेसिंग के लिए वेक्टर ऑपरेशन का उपयोग भी कर सकें, जो आगे की चीज़ों को गति देगा।

मेरे पास अच्छे परिणाम हैं ( memmapfile() का उपयोग करते हुए यह स्मृति डेटा प्रतिलिपि की मात्रा को कम करता है, और कर्नेल के आईओ बफरिंग का उपयोग करता है। संपूर्ण फ़ाइल को मानचित्रित करने के लिए आपको पर्याप्त निशुल्क पता स्थान (हालांकि वास्तविक मुक्त मेमोरी नहीं) की आवश्यकता है, और आउटपुट चर को पकड़ने के लिए पर्याप्त निःशुल्क मेमोरी (जाहिर है!)

नीचे उदाहरण का उदाहरण int32 प्रकार के दो-स्तंभ मैट्रिक्स data में एक पाठ फ़ाइल को पढ़ता है।

 fname = 'file.txt'; fstats = dir(fname); % Map the file as one long character string m = memmapfile(fname, 'Format', {'uint8' [ 1 fstats.bytes] 'asUint8'}); textdata = char(m.Data(1).asUint8); % Use textscan() to parse the string and convert to an int32 matrix data = textscan(textdata, '%d %d', 'CollectOutput', 1); data = data{:}; % Tidy up! clear('m') 

आपको वास्तव में वही प्राप्त करने के लिए textscan() के मापदंडों के साथ बेला होने की आवश्यकता हो सकती है – ऑनलाइन दस्तावेज़ देखें।

मैंने पाया है कि MATLAB सीएसवी फाइलों को पाठ फ़ाइलों की तुलना में काफी अधिक पढ़ता है, इसलिए यदि आपकी पाठ फ़ाइल को कुछ अन्य सॉफ्टवेयर का उपयोग करके सीएसवी में परिवर्तित करना संभव है, तो यह मैटलब के संचालन को काफी तेज कर सकता है