Чтение байтов намного медленнее, чем чтение строк из файла - PullRequest
0 голосов
/ 26 апреля 2020

Я создал 2 файла сравнения, в которые я записал сериализованный объект в файл, один является строковым типом, а другие байтами.

Считывая данные обратно, StreamReader оказывается примерно в 200 раз быстрее чем MemoryStream. Я делаю что-то неправильно? Есть ли способ ускорить чтение байтов из файла?

Полный исполняемый код приведен ниже:

using MessagePack;
using System;
using System.Diagnostics;
using System.IO;
using System.Runtime.Serialization;
using System.Text;
using Utf8Json;

namespace BenchmarkSerializer
{
    public class Test
    {
        public void RunTest()
        {
            // Build source files
            int lineCount = 50000;
            string json = "{\"type\": \"second\", \"error\": null, \"id\": 15644, \"value\": 451.3 }";
            SomeData concreteObject = JsonSerializer.Deserialize<SomeData>(json); // Create object from json using utf8json
            string baseDirectory = AppDomain.CurrentDomain.BaseDirectory;
            string stringTextFile = Path.Combine(baseDirectory, "1string.txt");
            string byteTextFile = Path.Combine(baseDirectory, "1byte.txt");

            if (File.Exists(stringTextFile))
            {
                File.Delete(stringTextFile);
            }


            if (File.Exists(byteTextFile))
            {
                File.Delete(byteTextFile);
            }

            // Build string test file
            byte[] byteArray = MessagePackSerializer.Typeless.Serialize(concreteObject);
            string base64String = Convert.ToBase64String(byteArray);
            using (var fs = new FileStream(stringTextFile, FileMode.Append, FileAccess.Write, FileShare.None))
            {
                using (StreamWriter sr = new StreamWriter(fs))
                {
                    for (int i = 0; i < lineCount; i++)
                    {
                        sr.WriteLine(base64String);
                    }
                }
            }

            // Build byte test file
            using (var fs = new FileStream(byteTextFile, FileMode.Append, FileAccess.Write, FileShare.None))
            {
                for (int i = 0; i < lineCount; i++)
                {
                    MessagePackSerializer.Typeless.Serialize(fs, concreteObject);
                }
            }

            //Read string test file
            Stopwatch stopwatch = new Stopwatch();
            stopwatch.Start();
            int count = 0;
            using (var fs = new FileStream(stringTextFile, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
            {
                using (var sr = new StreamReader(fs, Encoding.UTF8))
                {
                    while (sr.Peek() >= 0)
                    {
                        //Debug.WriteLine(count++);
                        string line = sr.ReadLine();
                        byte[] bytes = Convert.FromBase64String(line);
                        var obj = MessagePackSerializer.Typeless.Deserialize(bytes);

                    }
                }
            }

            long t1 = stopwatch.ElapsedMilliseconds;

            // Read Byte test file - streaming bytes seems slow
            int count2 = 0;
            var readTest = File.ReadAllBytes(byteTextFile);
            MemoryStream stream = new MemoryStream(readTest);
            while (stream.Position < stream.Length)
            {
                //Debug.WriteLine(count2++);
                var obj = MessagePackSerializer.Typeless.Deserialize(stream);
            }
            long t2 = stopwatch.ElapsedMilliseconds;

            Console.WriteLine($"String: {t1} Byte: {t2 - t1}");
            Console.ReadLine();
        }
    }

    [MessagePackObject]
    public class SomeData
    {
        public SomeData(string type, string error, int id, double value)
        {
            Type = type;
            Error = error;
            Id = id;
            Value = value;
        }

        [Key(0)]
        [DataMember(Name = "type", EmitDefaultValue = false)]
        public string Type { get; set; }

        [Key(1)]
        [DataMember(Name = "error", EmitDefaultValue = false)]
        public string Error { get; set; }

        [Key(2)]
        [DataMember(Name = "id", EmitDefaultValue = false)]
        public int Id { get; set; }

        [Key(3)]
        [DataMember(Name = "value", EmitDefaultValue = false)]
        public double Value { get; set; }
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...