2011-02-04 15 views
16

मेरे पास यह प्रोजेक्ट है, जिसे Memcached.Js कहा जाता है, जो कि मेडेकैड सर्वर का एक बंदरगाह Node.js. है।बफर बनाम स्ट्रिंग गति: स्ट्रिंग तेज क्यों है?

मैं मेमोरी पदचिह्न और प्रदर्शन की तुलना में स्ट्रिंग्स और बफर के साथ घूम रहा हूं। स्मृति के लिए, कोई सवाल नहीं है कि बफर सही विकल्प है।

लेकिन मेरे आश्चर्य के लिए यह प्रदर्शन के लिए भी सच नहीं है। स्ट्रिंग मैनिपुलेशन करना बफर का उपयोग करने से तेज है। यह मैं क्या करने की कोशिश की है:

// Option 1: data.toString() - amazing, but it's the best one 
var commandDataStr = mdata.data.toString().substr(startPos, bytes); 
var commandData = new Buffer(commandDataStr); 

// Option 2: data.slice().toString() - the same as above... What? 
var commandDataStr = mdata.data.slice(startPos, startPos + bytes).toString(); 
var commandData = new Buffer(commandDataStr); 

// Option 3: data.slice() - bad 
var commandData = mdata.data.slice(startPos, startPos + bytes); 

// Option 4: data.copy() - bad as well 
var commandData = new Buffer(bytes); 
mdata.data.copy(commandData, 0, startPos, startPos + bytes); 

पूरा कोड यहाँ है: https://github.com/dalssoft/memcached.js/blob/master/lib/memcached.ascii.commands.js#L72

परीक्षण कोड: ruby test/from_clients/perf_test.rb

परीक्षण से पता चला है कि स्ट्रिंग्स तेजी से बफर से कर रहे हैं। चूंकि यह मेरी अपेक्षा नहीं कर रहा था, मुझे लगता है कि मैं शायद कुछ गलत कर रहा हूं, लेकिन मुझे यह बिल्कुल नहीं मिल रहा है कि यह क्या है।

क्या कोई मेरी मदद कर सकता है?

Tks!

+0

आप एक छोटे से परीक्षण मामले के साथ गति व्यवहार को पुनः कर सकते हैं? यदि ऐसा है, तो एक बग रिपोर्ट भेजें। – btilly

+0

मैं इस स्क्रिप्ट का उपयोग करके प्रदर्शन को चकित कर रहा हूं: https://github.com/dalssoft/memcached.js/blob/master/test/from_clients/perf_test.rb –

उत्तर

21

स्ट्रिंग्स V8 में अंतर्निहित हैं, और वीएम के भीतर स्मृति आवंटित करते हैं। बफर को सभी स्ट्रिंग ऑपरेशंस को तेज़ नहीं करने के लिए जोड़ा गया था, लेकिन बाइनरी डेटा का प्रतिनिधित्व करने के लिए, जहां स्ट्रिंग्स यूनिकोड हैं।

सॉकेट में बड़ी मात्रा में डेटा लिखते समय, यह डेटा को बाइनरी प्रारूप में रखने के लिए अधिक कुशल है, बनाम यूनिकोड से कनवर्ट करना।

तो आम परिचालनों के लिए, जैसे कि कॉन्सट, मुझे आश्चर्य नहीं है स्ट्रिंग्स तेज़ हैं।

13

Buffer.slice नोड में महंगा है। मैंने पाया है कि पैटर्न:

buffer.slice(start, end).toString(encoding) 

था 10 से अधिक बार पैटर्न की तुलना में धीमी:

buffer.toString(encoding, start, end) 

हालांकि टुकड़ा किसी भी नए बफर आवंटित नहीं है, यह एक महत्वपूर्ण लागत का कारण बन रहा है । कोड पर एक कर्सर देखो से, मेरा अनुमान है कि बाहरी आवंटित बफर को v8 (SetIndexedPropertiesToExternalArrayData के माध्यम से) को उजागर करने के कारण इसे बफर ऑब्जेक्ट के लिए अपने जेनरेट कोड को अपडेट करना पड़ता है।

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

अधिक इस पर विचार: http://geochap.wordpress.com/2011/05/03/node-buffers/

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