C#4.5的文件读取性能同步异步VS [英] C# 4.5 file read performance sync vs async

查看:214
本文介绍了C#4.5的文件读取性能同步异步VS的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们正试图测量读了一系列使用同步方法V​​S异步文件之间的性能。期待有关于两者之间的相同时间,但原来使用异步大约是5.5倍速度较慢。

We're trying to measure the performance between reading a series of files using sync methods vs async. Was expecting to have about the same time between the two but turns out using async is about 5.5x slower.

这可能是由于管理线程的开销,但只是想知道你的意见。也许我们只是测量计时错误。

This might be due to the overhead of managing the threads but just wanted to know your opinion. Maybe we're just measuring the timings wrong.

这些是被测试的方法:

    static void ReadAllFile(string filename)
    {
        var content = File.ReadAllBytes(filename);
    }

    static async Task ReadAllFileAsync(string filename)
    {
        using (var file = File.OpenRead(filename))
        {
            using (var ms = new MemoryStream())
            {
                byte[] buff = new byte[file.Length];
                await file.ReadAsync(buff, 0, (int)file.Length);
            }
        }
    }

这是运行它们并启动秒表方法:

And this is the method that runs them and starts the stopwatch:

    static void Test(string name, Func<string, Task> gettask, int count)
    {
        Stopwatch sw = new Stopwatch();

        Task[] tasks = new Task[count];
        sw.Start();
        for (int i = 0; i < count; i++)
        {
            string filename = "file" + i + ".bin";
            tasks[i] = gettask(filename);
        }
        Task.WaitAll(tasks);
        sw.Stop();
        Console.WriteLine(name + " {0} ms", sw.ElapsedMilliseconds);

    }

这是从这里所有运行:

Which is all run from here:

    static void Main(string[] args)
    {
        int count = 10000;

        for (int i = 0; i < count; i++)
        {
            Write("file" + i + ".bin");
        }

        Console.WriteLine("Testing read...!");            

        Test("Read Contents", (filename) => Task.Run(() => ReadAllFile(filename)), count);
        Test("Read Contents Async", (filename) => ReadAllFileAsync(filename), count);

        Console.ReadKey();
    }

和辅助写入方式:

    static void Write(string filename)
    {
        Data obj = new Data()
        {
            Header = "random string size here"
        };
        int size = 1024 * 20; // 1024 * 256;

        obj.Body = new byte[size];

        for (var i = 0; i < size; i++)
        {
            obj.Body[i] = (byte)(i % 256);
        }

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

        MemoryStream ms = new MemoryStream();
        Serializer.Serialize(ms, obj);
        ms.Position = 0;

        using (var file = File.Create(filename))
        {
            ms.CopyToAsync(file).Wait();
        }

        sw.Stop();
        //Console.WriteLine("Writing file {0}", sw.ElapsedMilliseconds); 
    }

结果:

-Read Contents 574 ms
-Read Contents Async 3160 ms

真的会AP preciate如果有人能为我们搜索的协议栈和网络,但真的不能找到一个合适的解释,阐明这一些轻。

Will really appreciate if anyone can shed some light on this as we searched the stack and the web but can't really find a proper explanation.

推荐答案

有很多事情不对的测试code。最值得注意的是,你的异步测试并没有使用异步I / O;与文件流,你必须明确地打开它们为异步否则你只是在做一个后台线程同步操作。另外,文件的尺寸非常小,可以容易地进行高速缓存。

There are lots of things wrong with the testing code. Most notably, your "async" test does not use async I/O; with file streams, you have to explicitly open them as asynchronous or else you're just doing synchronous operations on a background thread. Also, your file sizes are very small and can be easily cached.

我修改了测试code写出来的更大的文件,有可比同步异步VS code,并且使异步code异步的:

I modified the test code to write out much larger files, to have comparable sync vs async code, and to make the async code asynchronous:

static void Main(string[] args)
{
    Write("0.bin");
    Write("1.bin");
    Write("2.bin");

    ReadAllFile("2.bin"); // warmup

    var sw = new Stopwatch();
    sw.Start();
    ReadAllFile("0.bin");
    ReadAllFile("1.bin");
    ReadAllFile("2.bin");
    sw.Stop();

    Console.WriteLine("Sync: " + sw.Elapsed);

    ReadAllFileAsync("2.bin").Wait(); // warmup

    sw.Restart();
    ReadAllFileAsync("0.bin").Wait();
    ReadAllFileAsync("1.bin").Wait();
    ReadAllFileAsync("2.bin").Wait();
    sw.Stop();

    Console.WriteLine("Async: " + sw.Elapsed);

    Console.ReadKey();
}

static void ReadAllFile(string filename)
{
    using (var file = new FileStream(filename, FileMode.Open, FileAccess.Read, FileShare.Read, 4096, false))
    {
        byte[] buff = new byte[file.Length];
        file.Read(buff, 0, (int)file.Length);
    }
}

static async Task ReadAllFileAsync(string filename)
{
    using (var file = new FileStream(filename, FileMode.Open, FileAccess.Read, FileShare.Read, 4096, true))
    {
        byte[] buff = new byte[file.Length];
        await file.ReadAsync(buff, 0, (int)file.Length);
    }
}

static void Write(string filename)
{
    int size = 1024 * 1024 * 256;
    var data = new byte[size];
    var random = new Random();
    random.NextBytes(data);
    File.WriteAllBytes(filename, data);
}

在我的机器上,这种测试(建于发布,调试器外运行)产生这些数字:

On my machine, this test (built in Release, run outside the debugger) yields these numbers:

Sync: 00:00:00.4461936
Async: 00:00:00.4429566

这篇关于C#4.5的文件读取性能同步异步VS的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆