数据结构c语言的算法分析(C配置文件存储各种序列化算法性能比较)
数据结构c语言的算法分析(C配置文件存储各种序列化算法性能比较)下面是在 ssd 的读写性能,平均时间是读取 91.8 毫秒,写入 119.4 毫秒 var fileInfo = new FileInfo(@"E:\回收站\xx2"); if (!fileInfo.Exists) { var foo = Foo.BegaymouniWaloujijou(); var stopwatch = new Stopwatch(); stopwatch.Start(); var stream = fileInfo.OpenWrite(); using (stream) { Serializer.Serialize(stream foo); } stopwatch.Stop(); Console.WriteLine("写入" stopwatch.ElapsedMilliseconds); } else { var stopwa
本文比较多个方式进行配置文件的存储,对比各个不同算法的读写性能。
在应用软件启动的时候,需要读取配置文件,但是启动的性能很重要,所以需要有一个很快的读取配置文件的方法。
如果你不想看过程,那么请看拖动滚动条
本文将会比较三个世界上最好的序列化算法,一个是 json 、一个是 ProtoBuf 、一个是 wire
原来我的软件在启动的时候是需要读取很多个文件,因为每个模块的配置都不同,所有模块的配置都是模块自己查找配置文件读取,然而大家都知道,在机械硬盘,随机读取文件的性能很差。现在虽然很多用户都是使用固态硬盘,但是对于启动性能优化,还是要尽量减少在软件启动过程的读取文件。
我询问了奎爷,他是一位强大的程序员,他告诉我,谷歌浏览器把很多零碎的文件,如历史记录和密码都压缩为一个文件,这样的启动时候,顺序读取性能很快,所以浏览器才可以快速启动。
于是我就开始了准备把所有的模块的配置文件合为一个,在合并的时候需要做序列化,因为存在很多模块都是使用自己实现的方式进行序列化。
var fileInfo = new FileInfo(@"E:\回收站\xx2"); if (!fileInfo.Exists) { var foo = Foo.BegaymouniWaloujijou(); var stopwatch = new Stopwatch(); stopwatch.Start(); var stream = fileInfo.OpenWrite(); using (stream) { Serializer.Serialize(stream foo); } stopwatch.Stop(); Console.WriteLine("写入" stopwatch.ElapsedMilliseconds); } else { var stopwatch = new Stopwatch(); stopwatch.Start(); var stream = fileInfo.OpenRead(); using (stream) { stream.Seek(0 SeekOrigin.Begin); var foo = Serializer.Deserialize<Foo>(stream); } stopwatch.Stop(); Console.WriteLine("读取时间" stopwatch.ElapsedMilliseconds); fileInfo.Delete(); } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
我尝试在 ssd 和 机械硬盘读写,比较两个的性能
下面是在 ssd 的读写性能,平均时间是读取 91.8 毫秒,写入 119.4 毫秒
读取 写入 90 108 84 115 93 142 80 109 112 123 1 2 3 4 5 6
我尝试在机械硬盘读写,平均时间是读取104.4毫秒,写入140.2毫秒
读取 写入 95 127 115 163 107 168 98 128 107 115 1 2 3 4 5 6
wire
这是传说中最快的序列化库,我安装了 Wire 然后使用下面的代码,运行 5 次计算读写时间
var fileInfo = new FileInfo(@"E:\回收站\xx3"); if (!fileInfo.Exists) { var foo = Foo.BegaymouniWaloujijou(); var stopwatch = new Stopwatch(); stopwatch.Start(); var stream = fileInfo.OpenWrite(); using (stream) { var serializer = new Wire.Serializer(); serializer.Serialize(foo stream); } stopwatch.Stop(); Console.WriteLine("写入" stopwatch.ElapsedMilliseconds); } else { var stopwatch = new Stopwatch(); stopwatch.Start(); var stream = fileInfo.OpenRead(); using (stream) { var serializer = new Wire.Serializer(); var foo = serializer.Deserialize<Foo>(stream); } stopwatch.Stop(); Console.WriteLine("读取时间" stopwatch.ElapsedMilliseconds); fileInfo.Delete(); } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
虽然小伙伴说他是最快的,但是在我的设备,平均读取125.8毫秒,写入101.2毫秒
读取 写入 109 104 106 94 111 92 190 90 113 126 1 2 3 4 5 6
自己写的
最后我尝试自己写了简单的序列化,因为存放的信息是key-value,我可以控制包含的字符串都是不带换行,也就是我可以一行放 value 一行放关键字。
var fileInfo = new FileInfo(@"E:\回收站\xx7"); if (!fileInfo.Exists) { var foo = Foo.BegaymouniWaloujijou(); var stopwatch = new Stopwatch(); stopwatch.Start(); using (var stream = new StreamWriter(fileInfo.OpenWrite())) { foreach (var temp in foo.CurmobeKallbu) { stream.WriteLine(temp.Key); stream.WriteLine(temp.Value); } } stopwatch.Stop(); Console.WriteLine("写入" stopwatch.ElapsedMilliseconds); } else { var stopwatch = new Stopwatch(); stopwatch.Start(); var stream = fileInfo.OpenText(); using (stream) { var str = stream.ReadToEnd().Split('\n'); var foo = new Foo(); foo.CurmobeKallbu = new Dictionary<string string>(str.Length / 2); string key = null; foreach (var temp in str) { if (key == null) { key = temp; } else { foo.CurmobeKallbu.Add(key temp); key = null; } } } stopwatch.Stop(); Console.WriteLine("读取时间" stopwatch.ElapsedMilliseconds); fileInfo.Delete(); } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51
我发现在 ssd 和在机械硬盘读写性能几乎没有相差,有时候相同程序在 ssd 运行的时间比在机械硬盘多。在我测试了自己写的程序才知道,最多的时间在序列化,读取文件的时间反而可以被忽略。使用自己写的序列化读取1毫秒,写入7.2毫秒,所以这么简单的配置文件还是自己做序列化比较快。
读取 写入 1 6 1 8 1 8 1 5 1 9 1 2 3 4 5 6
建议
在软件启动的时候,还有一个读取文件是加载库,如果我使用了第三方的 dll ,那么在启动的时候我就需要加载这个 dll ,但是我读取的配置文件只有不到 100 k 但是我加载的几个库都是很大。加载库的时间已经足够我自己写的序列化读取完成,需要知道,在启动程序的时候不是把所有程序的库都加载,只有在用到的时候才去读取库,读取库也是需要时间,所以程序启动的时候尽量不要引用不相关的库。
所以在启动的过程如果需要读取配置文件,还是使用自己写序列化,而且要求自己写的配置文件很稳定,不要在启动的时候出现异常。
自己写配置文件可以在一个线程进行读取,然后把整个程序所有在启动过程使用配置文件的地方都删除,只有软件启动的过程读取的文件只有很少的几个,最好是一个,这样才能保证软件启动的性能。
代码:C# 配置文件存储 各种序列化算法性能比较 程序1.1-CSDN下载
如果没有积分需要代码请联系我