2010-08-22 14 views
9

मैं अक्सर पढ़ता हूं कि बाइनरीफॉर्मेटर के बेहतर प्रदर्शन तब XmlSerializer है। जिज्ञासा से, मैंने एक टेस्ट-ऐप लिखा था।प्रदर्शन: बाइनरीफॉर्मेटर बनाम एक्सएमएलएसरियलाइज़र

एक wtf पल ... एक्सएमएल बिन (विशेष रूप से deserialization) से इतना तेज क्यों है?

using System; 
using System.Collections.Generic; 
using System.Runtime.Serialization; 
using System.Xml.Serialization; 
using System.Runtime.Serialization.Formatters.Binary; 
using System.IO; 

namespace SerPlayground 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      var items = new List<TestClass>(); 
      for (int i = 0; i < 1E6; i++) 
      { 
       items.Add(new TestClass() { Name = i.ToString(), Id = i }); 
      } 

      File.Delete("test.bin"); 
      using (var target = new FileStream("test.bin", FileMode.OpenOrCreate)) 
      { 
       System.Threading.Thread.Sleep(1000); 
       var bin = new BinaryFormatter(); 
       var start = DateTime.Now; 
       bin.Serialize(target, items); 
       Console.WriteLine("Bin: {0}", (DateTime.Now - start).TotalMilliseconds); 

       target.Position = 0; 
       System.Threading.Thread.Sleep(1000); 
       start = DateTime.Now; 
       bin.Deserialize(target); 
       Console.WriteLine("Bin-D: {0}", (DateTime.Now - start).TotalMilliseconds); 
      } 

      File.Delete("test.xml"); 
      using (var target = new FileStream("test.xml", FileMode.OpenOrCreate)) 
      { 
       System.Threading.Thread.Sleep(1000); 
       var xml = new XmlSerializer(typeof(List<TestClass>)); 
       var start = DateTime.Now; 
       xml.Serialize(target, items); 
       Console.WriteLine("Xml: {0}", (DateTime.Now - start).TotalMilliseconds); 

       target.Position = 0; 
       System.Threading.Thread.Sleep(1000); 
       start = DateTime.Now; 
       xml.Deserialize(target); 
       Console.WriteLine("Xml-D: {0}", (DateTime.Now - start).TotalMilliseconds); 
      } 

      Console.ReadKey(); 
     } 
    } 

    [Serializable] 
    public class TestClass 
    { 
     public string Name { get; set; } 
     public int Id { get; set; } 
    } 
} 

मेरे परिणाम:

Bin: 13472.7706 
Bin-D: 121131.9284 
Xml: 8917.51 
Xml-D: 12841.7345 
+1

Deserialization क्रमबद्धता की तुलना में कहीं धीमी है। क्या आप अपना नमूना दोनों को करने के लिए संशोधित कर सकते हैं? यह एक और अधिक दिलचस्प तुलना होगी। –

+0

हाय, मैं आपके कुछ परीक्षणों को एकाधिक (100+?) बार चलाने पर विचार करता हूं - या तो लूप में या बिना स्टार्टअप (फॉर्मेटर्स/सीरियलाइज़र बनाना) के साथ। कई और रनों के परिणाम को समय देने से आपको प्रदर्शन की एक और सटीक तस्वीर मिल सकती है। समय-समय पर स्टॉपवॉच क्लास का उपयोग करने पर भी विचार करें क्योंकि मुझे लगता है कि यह उच्च-प्रदर्शन टाइमर का उपयोग करता है जहां कहीं भी है। यदि आपको अभी भी एक तेज़ एक्सएमएल सीरियलाइजेशन मिलता है तो यह जानना अच्छा होगा कि क्यों! – Jennifer

+0

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

उत्तर

7

क्योंकि आप एक वस्तु किसी भी गुण नहीं है कि serialising कर रहे हैं।

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

मैं अपने कोड के लिए यह परिवर्तन किया:

items.Add("asfd"); 

और मैं इस परिणाम मिलता है:

Xml: 1219.0541 
Bin: 165.0002 

अंतर का एक हिस्सा निश्चित रूप से है कि एक्सएमएल फ़ाइल के बारे में दस गुना से भी बड़ा है द्विआधारी फ़ाइल।

+1

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

+2

एएसएफडी - अमेरिकी डिजाइनर फर्नीचर डिजाइनर? –

+0

और रॉबर्ट हार्वे: मैंने एक और जटिल वर्ग जोड़ा है ... एक्सएमएल और बीआईएन का स्वैपिंग अब कोई बदलाव नहीं करता है ... परिणाम एक ही एक्सएमएल तेज है – Lukas

3

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

कहा जा रहा है कि XmlSerializer और बाइनरीफॉर्मेटर (स्पष्ट से अलग) के बीच एक महत्वपूर्ण अंतर यह है कि XmlSerializer संदर्भों का ट्रैक रखने का कोई प्रयास नहीं करता है। यदि आपके ऑब्जेक्ट ग्राफ़ में एक ही ऑब्जेक्ट के कई संदर्भ हैं, तो आपको XML में कई प्रतियां मिलती हैं और इसे deserialization पर ठीक से हल नहीं किया जाता है (एक ऑब्जेक्ट में वापस)। यदि आपके पास चक्र हैं तो इससे भी बदतर, ऑब्जेक्ट को क्रमबद्ध नहीं किया जा सकता है। बाइनरीफॉर्मेटर के साथ इसकी तुलना करें जो संदर्भों का ट्रैक रखता है और विश्वसनीय रूप से वस्तु ग्राफ को पुनर्निर्मित करता है इससे कोई फर्क नहीं पड़ता कि कितने, और किस प्रकार के ऑब्जेक्ट संदर्भ हो सकते हैं। शायद इस सुविधा के ऊपरी हिस्से में गरीब प्रदर्शन के लिए जिम्मेदार है?

XmlSerializer पर बाइनरीफॉर्मेटर का उपयोग करने का मुख्य कारण आकार आउटपुट का है, धारावाहिक/deserialization के प्रदर्शन नहीं। (पाठ के निर्माण की भूमि के ऊपर, इतना महान नहीं है, यह उस xml पाठ कि महंगा है के परिवहन है।)

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