.NET 4.5 文件读取性能同步与异步

2024-01-07

我们正在尝试测量使用同步方法与异步方法读取一系列文件之间的性能。原本期望两者之间的时间大致相同,但结果发现使用异步大约慢 5.5 倍。

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

这些是正在测试的方法:

    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);
            }
        }
    }

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

    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);

    }

这一切都是从这里运行的:

    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

当我们搜索堆栈和网络但无法真正找到正确的解释时,如果有人能够阐明这一点,我将非常感激。


测试代码有很多问题。最值得注意的是,您的“异步”测试不使用异步 I/O;对于文件流,您必须显式地以异步方式打开它们,否则您只是在后台线程上执行同步操作。此外,您的文件大小非常小,可以轻松缓存。

我修改了测试代码以写出更大的文件,具有可比的同步代码与异步代码,并使异步代码异步:

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);
}

在我的机器上,此测试(内置于版本中,在调试器外部运行)产生以下数字:

Sync: 00:00:00.4461936
Async: 00:00:00.4429566
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

.NET 4.5 文件读取性能同步与异步 的相关文章

  • Signalr 在生产服务器中总是陷入长轮询

    当我在服务器中托管应用程序时 它会检查服务器端事件并始终回退到长轮询 服务器托管环境为Windows Server 2012 R1和IIS 7 5 无论如何 我们是否可以解决这个问题 https cloud githubuserconten
  • 如何在没有 Control.Invoke() 的情况下从后台线程修改控件属性

    最近 我们遇到了一些旧版 WinForms 应用程序 我们需要更新一些新功能 在专家测试该应用程序时 发现一些旧功能被破坏 无效的跨线程操作 现在 在您认为我是新手之前 我确实有一些 Windows 窗体应用程序的经验 我不是专家 但我认为
  • FFMPEG Seeking 带来音频伪影

    我正在使用 ffmpeg 实现音频解码器 在读取音频甚至搜索已经可以工作时 我无法找到一种在搜索后清除缓冲区的方法 因此当应用程序在搜索后立即开始读取音频时 我没有任何工件 avcodec flush buffers似乎对内部缓冲区没有任何
  • fgets() 和 Ctrl+D,三次才能结束?

    I don t understand why I need press Ctrl D for three times to send the EOF In addition if I press Enter then it only too
  • 如何在我的应用程序中使用 Windows Key

    Like Windows Key E Opens a new Explorer Window And Windows Key R Displays the Run command 如何在应用程序的 KeyDown 事件中使用 Windows
  • 写入和读取文本文件 - C# Windows 通用平台应用程序 Windows 10

    有用 但在显示任何内容之前 您必须在文本框中输入内容 我想那是因为我使用了 TextChanged 事件处理程序 如果我希望它在没有用户交互的情况下显示文本文件的内容 我应该使用哪个事件处理程序 因此 我想在按下按钮时将一些数据写入 C W
  • 如何针对 Nancy 中的 Active Directory 进行身份验证?

    这是一篇过时的文章 但是http msdn microsoft com en us library ff650308 aspx paght000026 step3 http msdn microsoft com en us library
  • 按字典顺序对整数数组进行排序 C++

    我想按字典顺序对一个大整数数组 例如 100 万个元素 进行排序 Example input 100 21 22 99 1 927 sorted 1 100 21 22 927 99 我用最简单的方法做到了 将所有数字转换为字符串 非常昂贵
  • 在 ASP.Net Core 2.0 中导出到 Excel

    我曾经使用下面的代码在 ASP NET MVC 中将数据导出到 Excel Response AppendHeader content disposition attachment filename ExportedHtml xls Res
  • 编译的表达式树会泄漏吗?

    根据我的理解 JIT 代码在程序运行时永远不会从内存中释放 这是否意味着重复调用 Compile 表达式树上会泄漏内存吗 这意味着仅在静态构造函数中编译表达式树或以其他方式缓存它们 这可能不那么简单 正确的 他们可能是GCed Lambda
  • 是否有比 lex/flex 更好(更现代)的工具来生成 C++ 分词器?

    我最近将源文件解析添加到现有工具中 该工具从复杂的命令行参数生成输出文件 命令行参数变得如此复杂 以至于我们开始允许它们作为一个文件提供 该文件被解析为一个非常大的命令行 但语法仍然很尴尬 因此我添加了使用更合理的语法解析源文件的功能 我使
  • 我的 strlcpy 版本

    海湾合作委员会 4 4 4 c89 我的程序做了很多字符串处理 我不想使用 strncpy 因为它不会终止 我不能使用 strlcpy 因为它不可移植 只是几个问题 我怎样才能让我的函数正常运行 以确保它完全安全稳定 单元测试 这对于生产来
  • 更改窗口的内容 (WPF)

    我创建了一个简单的 WPF 应用程序 它有两个 Windows 用户在第一个窗口中填写一些信息 然后单击 确定 这会将他们带到第二个窗口 这工作正常 但我试图将两个窗口合并到一个窗口中 这样只是内容发生了变化 我设法找到了这个更改窗口内容时
  • 将日期参数传递给对 MVC 操作的 ajax 调用的安全方法

    我有一个 MVC 操作 它的参数之一是DateTime如果我通过 17 07 2012 它会抛出一个异常 指出参数为空但不能有空值 但如果我通过01 07 2012它被解析为Jan 07 2012 我将日期传递给 ajax 调用DD MM
  • char指针或char变量的默认值是什么[重复]

    这个问题在这里已经有答案了 下面是我尝试打印 char 变量和指针的默认值 值的代码 但无法在控制台上看到它 它是否有默认值或只是无法读取 ASCII 范围 include
  • 如何构建印度尼西亚电话号码正则表达式

    这些是一些印度尼西亚的电话号码 08xxxxxxxxx 至少包含 11 个字符长度 08xxxxxxxxxxx 始终以 08 开头 我发现这个很有用 Regex regex new Regex 08 0 9 0 9 0 9 0 9 0 9
  • GDK3/GTK3窗口更新的精确定时

    我有一个使用 GTK 用 C 语言编写的应用程序 尽管该语言对于这个问题可能并不重要 这个应用程序有全屏gtk window与单个gtk drawing area 对于绘图区域 我已经通过注册了一个刻度回调gtk widget add ti
  • 如何在 C# 中播放在线资源中的 .mp3 文件?

    我的问题与此非常相似question https stackoverflow com questions 7556672 mp3 play from stream on c sharp 我有音乐网址 网址如http site com aud
  • 如何连接字符串和常量字符?

    我需要将 hello world 放入c中 我怎样才能做到这一点 string a hello const char b world const char C string a hello const char b world a b co
  • 不同类型的指针可以互相分配吗?

    考虑到 T1 p1 T2 p2 我们可以将 p1 分配给 p2 或反之亦然吗 如果是这样 是否可以不使用强制转换来完成 或者我们必须使用强制转换 首先 让我们考虑不进行强制转换的分配 C 2018 6 5 16 1 1 列出了简单赋值的约束

随机推荐

  • 如何从Excel列字母中获取列号(或索引)

    我搜索过这个网站并用谷歌搜索了一个公式 我需要根据字母计算 Excel 列号 例如 A 1 B 2 AA 27 AZ 52 AAA 703 在字母表随机循环后 代码似乎少了 1 位数字 AZ gt BA 少数字 它看起来还会从两个不同的输入
  • 如何检测 JComboBox 是否为空?

    如何检测 JComboBox 是否为空 是不是类似 combobox isEmpty 出了什么问题JComboBox getItemCount http docs oracle com javase 7 docs api javax swi
  • 隐马尔可夫模型 (HMM) 中的三态电话模型

    我想问一下HMM中3态电话模型的含义 本案例基于语音识别系统中的HMM理论 因此 该示例基于 HMM 中语音的声学建模 我从期刊论文中得到了这张示例图片 http www intechopen com source html 41188 m
  • 如何在 Github Atom Editor 中同步多台计算机的包和设置

    我已经在我的个人电脑和办公室电脑上安装了 Github Atom Editor 我想将设置和软件包同步到我的 Dropbox 帐户 这样当我登录办公室电脑时 它会自动下载或更新所有软件包和设置到我的家庭电脑 您是否尝试过使用原子同步设置 h
  • CMU Sphinx 是否可以通过 Maven 获得?

    我有一个可能需要 CMU Sphinx 的应用程序的想法 它可以通过 Maven 获得 还是需要手动添加 更新 CMUSphinx 将在一周左右的时间内在 sonatype 中提供 Maven 支持已经提交到 sphinx4 trunk 中
  • go-git:创建本地分支的正确方法,模拟“git分支 ”的行为?

    正如标题所示 我试图弄清楚如何使用创建本地分支go git与 Git CLI 命令给出相同结果的方式git branch
  • 防止“冒泡”? [复制]

    这个问题在这里已经有答案了 我不确定这是否真的在冒泡 我会解释一下 我有这个 div div text here div div 如何绑定点击事件 使其仅影响所包含的 div 如果我这样设置 jQuery div bind click fu
  • 使用elasticsearch实施建议“类别中的xxx”

    我想对产品实施类似亚马逊的 类别内 建议 亚马逊建议在特定类别中搜索给定术语 而不是全局搜索 这允许更具体的搜索和结果 有没有办法使用elasticsearch提供的建议功能之一来实现这一点 目前我的想法是从elasticsearch获取建
  • mongoDB vs mySQL——为什么一个在某些方面比另一个更好[关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi
  • 评估骰子滚动符号字符串

    Rules 编写一个接受字符串作为参数的函数 返回 表达式的评估值骰子记数法 http en wikipedia org wiki Dice notation 包括加法和乘法 为了澄清问题 这里是法律表达式的 EBNF 定义 roll po
  • 使用 Python 从文本中提取 IBAN

    我想用 Python 从文本中提取 IBAN 号码 这里的挑战是 IBAN 本身可以用多种方式编写 数字之间有空格 我发现很难将其转换为有用的正则表达式模式 我写了一个演示版 https regex101 com r PRDDaT 1它尝试
  • 使用 LINQ 进行编码是如何工作的?幕后发生了什么?

    例如 m lottTorqueTools From t In m lottTorqueTools Where Not t SlotNumber toolTuple SlotNumber And Not t StationIndex tool
  • java.lang.RuntimeException: android.database.sqlite.SQLiteException: 没有这样的表: media_store_extension (代码 1): ,

    我在 2021 年 10 月之后在 Play 商店上发布我的应用程序时遇到问题 错误表明该表media store extension不存在 问题是 我在项目中没有使用 SQLITE 所以我不知道是什么导致了这个异常 目标 sdk 是 30
  • 当单词不存在时,将 0 分配给某些单词

    这是我在 stackoverflow 上发表的第一篇文章 我对编码还比较陌生 所以 请耐心听我说 我正在做一个实验 有两组数据文档 文档1如下 TOPIC topic 0 5892 0 site 0 0371690427699 Intern
  • GLSL 着色器:在两个以上纹理之间进行插值

    我已经在 OpenGL 中实现了高度图 目前它只是一个正弦 余弦弯曲地形 目前我正在白色的 冰 和较暗的 石头 纹理之间进行插值 这是这样完成的 color mix texture2D ice layer tex texcoord text
  • 如何从给定的父节点获取所有子节点?

    我有一个父 子 ID 列表 并且希望获取给定父 ID 的所有子 ID 不存在空父级 顶级 ID 不会显示为子 ID 目前 父 子 ID 被记录为列表中的 KeyValuePair 但是如果更好的话 可以轻松更改为其他数据结构 List
  • aspnet 的最大值:MaxHttpCollectionKeys

    我有一个发布相当大数据的表单 但出现此错误 InvalidOperationException Operation is not valid due to the current state of the object System Web
  • JPanel 错误 - J 组件无法解析

    我有 JRE 系统库 JRE 1 8 x 库 我的线路出现错误 错误 无法解析类型 javax swing JComponent 它是从所需的 class 文件间接引用的 我怎样才能消除这个错误 这是屏幕截图 http i60 tinypi
  • 框架的私有模块映射

    我在用着这个答案 https stackoverflow com a 25250520 849645创建模块映射来为 CommonCrypto 创建模块 以便我可以在框架中使用它 然而 这样做意味着我使用此框架的任何项目都可以通过以下方式访
  • .NET 4.5 文件读取性能同步与异步

    我们正在尝试测量使用同步方法与异步方法读取一系列文件之间的性能 原本期望两者之间的时间大致相同 但结果发现使用异步大约慢 5 5 倍 这可能是由于管理线程的开销造成的 但只是想知道您的意见 也许我们只是测量了错误的时间 这些是正在测试的方法