2009-11-04 13 views
13

128³ युगल की एक बाइनरीफॉर्मेटर-क्रमबद्ध सरणी, 50 एमबी स्पेस लेती है। 128³ संरचना एस की एक सरणी को क्रमशः दो डबल फ़ील्ड प्रक्रिया के लिए 150 एमबी और 20 सेकंड से अधिक समय लेता है।बाइनरीफॉर्मेटर विकल्प

क्या तेजी से सरल विकल्प हैं जो कॉम्पैक्ट फाइलें उत्पन्न करेंगे? मेरी उम्मीद यह है कि उपरोक्त उदाहरण क्रमशः 16 और 32 एमबी लेते हैं, और प्रक्रिया के लिए दो सेकंड के तहत। मैंने प्रोटोबफ-नेट पर एक नज़र डाली, लेकिन ऐसा लगता है कि यह संरचना सरणी का भी समर्थन नहीं करता है।

पीएस: फ़ाइल आकार रिकॉर्ड करने में गलती करने के लिए मैं क्षमा चाहता हूं। बाइनरीफॉर्मेटर के साथ वास्तविक स्थान ओवरहेड बड़ा नहीं है।

उत्तर

4

सीरियलाइजिंग का मतलब है कि मेटाडेटा जोड़ा जाता है ताकि डेटा सुरक्षित रूप से deserialized किया जा सके, यही कारण है कि ओवरहेड का कारण बन रहा है। आप डेटा अपने आप को किसी भी मेटाडाटा के बिना क्रमानुसार हैं, तो आप डेटा के 16 MB के साथ अंत:

foreach (double d in array) { 
    byte[] bin = BitConverter.GetBytes(d); 
    stream.Write(bin, 0, bin.Length); 
} 

निश्चित रूप से इसका मतलब है आप डेटा अपने आप को भी deserialize करने के लिए है कि:

using (BinaryReader reader = new BinaryReader(stream)) { 
    for (int i = 0; i < array.Length; i++) { 
     byte[] data = reader.ReadBytes(8); 
     array[i] = BitConverter.ToDouble(data, 0); 
    } 
} 
7

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

मेरे सिस्टम पर 32 एमबी लिखने पर 0.5 सेकंड से कम समय लगता है, जिसमें स्ट्रीम के ओपन और क्लोज़ शामिल हैं।

आप इस तरह, डेटा लिखने के लिए अपने स्वयं के के लिए छोरों लिखने के लिए करना होगा:

struct Pair 
{ 
    public double X, Y; 
} 

static void WritePairs(string filename, Pair[] data) 
{ 
    using (var fs = System.IO.File.Create(filename)) 
    using (var bw = new System.IO.BinaryWriter(fs)) 
    { 
     for (int i = 0; i < data.Length; i++) 
     { 
      bw.Write(data[i].X); 
      bw.Write(data[i].Y); 
     } 
    } 
} 

static void ReadPairs(string fileName, Pair[] data) 
{ 
    using (var fs = System.IO.File.OpenRead(fileName)) 
    using (var br = new System.IO.BinaryReader(fs)) 
    { 
     for (int i = 0; i < data.Length; i++) 
     { 
      data[i].X = br.ReadDouble(); 
      data[i].Y = br.ReadDouble(); 
     } 
    } 
} 
+2

मैनुअल क्रमबद्धता वास्तव में बहुत तेजी से और कॉम्पैक्ट हो सकता है, लेकिन यह भी त्रुटि के लिए और प्रवण समय लेने वाली लिखने के लिए है। मैं कुछ ओवरहेड की उम्मीद करता हूं, लेकिन बाइनरीफॉर्मेटर के साथ यह अक्सर अनुचित होता है। –

+0

आप इसे जेनेरिक और/या इंटरफेस के साथ थोड़ा सा मित्र बना सकते हैं। लेकिन मेटा जोड़ने शुरू करें और आप जल्दी से फॉर्मेटर्स के ऊपरी हिस्से तक पहुंच जाएंगे। –

+0

हेनक पर स्पॉट। बाइनरीफॉर्मेटर लगभग * कुछ * के साथ काम करेगा। आपको किसी चीज से बेहतर प्रदर्शन की अपेक्षा करनी चाहिए जो आपको चाहिए और * केवल * जो आपको चाहिए। –

2

यह एक टिप्पणी के और अधिक है, लेकिन इसे जिस तरह से एक के लिए बहुत ज्यादा है ... मैं नहीं कर रहा हूँ अपने परिणामों को पुन: उत्पन्न करने में सक्षम। हालांकि, संरचना के साथ कुछ अतिरिक्त ओवरहेड है।

मेरे परीक्षण:

------------------------------------------------------------------------------- 
Testing array of structs 

Size of double: 8 
Size of doubles.bin: 16777244 
Size per array item: 8 
Milliseconds to serialize: 143 
------------------------------------------------------------------------------- 
------------------------------------------------------------------------------- 
Testing array of structs 

Size of dd struct: 16 
Size of structs.bin: 52428991 
Size per array item: 25 
Milliseconds to serialize: 9678 
------------------------------------------------------------------------------- 

कोड:

using System; 
using System.Collections.Generic; 
using System.Text; 
using System.Runtime.Serialization; 
using System.Runtime.Serialization.Formatters.Binary; 
using System.IO; 
using System.Diagnostics; 

namespace ConsoleApplication5 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      TestDoubleArray(); 
      TestStructArray(); 
     } 

     private static void TestStructArray() 
     { 

      Stopwatch stopWatch = new Stopwatch(); 
      stopWatch.Start(); 

      dd[] d1 = new dd[2097152]; 
      BinaryFormatter f1 = new BinaryFormatter(); 
      f1.Serialize(File.Create("structs.bin"), d1); 

      stopWatch.Stop(); 

      Debug.WriteLine("-------------------------------------------------------------------------------"); 
      Debug.WriteLine("Testing array of structs"); 
      Debug.WriteLine(""); 
      Debug.WriteLine("Size of dd struct: " + System.Runtime.InteropServices.Marshal.SizeOf(typeof(dd)).ToString()); 
      FileInfo fi = new FileInfo("structs.bin"); 
      Debug.WriteLine("Size of structs.bin: " + fi.Length.ToString()); 
      Debug.WriteLine("Size per array item: " + (fi.Length/2097152).ToString()); 
      Debug.WriteLine("Milliseconds to serialize: " + stopWatch.ElapsedMilliseconds); 
      Debug.WriteLine("-------------------------------------------------------------------------------"); 
     } 

     static void TestDoubleArray() 
     { 
      Stopwatch stopWatch = new Stopwatch(); 
      stopWatch.Start(); 

      double[] d = new double[2097152]; 
      BinaryFormatter f = new BinaryFormatter(); 
      f.Serialize(File.Create("doubles.bin"), d); 

      stopWatch.Stop(); 

      Debug.WriteLine("-------------------------------------------------------------------------------"); 
      Debug.WriteLine("Testing array of structs"); 
      Debug.WriteLine(""); 
      Debug.WriteLine("Size of double: " + sizeof(double).ToString()); 
      FileInfo fi = new FileInfo("test.bin"); 
      Debug.WriteLine("Size of doubles.bin: " + fi.Length.ToString()); 
      Debug.WriteLine("Size per array item: " + (fi.Length/2097152).ToString()); 
      Debug.WriteLine("Milliseconds to serialize: " + stopWatch.ElapsedMilliseconds); 
      Debug.WriteLine("-------------------------------------------------------------------------------"); 
     } 

     [Serializable] 
     struct dd 
     { 
      double a; 
      double b; 
     } 
    } 
} 
+0

सुधार के लिए धन्यवाद। मेरी गलती। अंतरिक्ष ओवरहेड बहुत बड़ा नहीं है। सीरियलाइज़र लेता है, हालांकि, अभी भी बहुत महत्वपूर्ण है। –

+0

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

+0

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

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