代码之家  ›  专栏  ›  技术社区  ›  Don Reba

二进制格式化程序替代方案

  •  13
  • Don Reba  · 技术社区  · 16 年前

    结构 s带两个 字段占用150 MB,处理时间超过20秒。

    结构 阵列。

    3 回复  |  直到 16 年前
        1
  •  8
  •   Henk Holterman    16 年前

    如果使用BinaryWriter而不是序列化程序,您将获得所需的(最小)大小。
    我不确定速度,但试试看。

    你得自己写 对于 循环以写入数据,如下所示:

    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
  •  5
  •   Guffa    16 年前

    序列化意味着添加元数据以便可以安全地反序列化数据,这就是导致开销的原因。如果您自己序列化数据而不使用任何元数据,则最终会得到16 MB的数据:

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

    当然,这意味着您还必须自己反序列化数据:

    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);
       }
    }
    
        3
  •  3
  •   Austin Salonen gmlacrosse    16 年前

    这更多的是一个评论,但对一个人来说太多了。。。我无法复制你的结果。然而,这个结构还有一些额外的开销。

    -------------------------------------------------------------------------------
    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;
            }
        }
    }
    
    推荐文章