1 回答
米琪卡哇伊
TA贡献1998条经验 获得超6个赞
假设您在谈论 IO:
想象一下,你有一个var fin *os.File
包裹在缓冲区中的文件,var instrm *bufio.Reader
. 现在假设您正在编写某种解析器,一次读取一个字符(比如字节)。包bufio实现缓冲 I/O。
如果你调用myParser.Parse(fin)
你将调用.Read
4,194,304 次来读取每个字节,这将使系统调用 4,194,304 次,这将导致 4,194,304 次上下文切换。上下文切换是控制从用户空间程序转移到操作系统的时间,并且是最慢的(非 IO)操作之一。在操作系统未合并/预取 IO 请求的情况下,您的 IO 设备也极有可能一次查找和读取一个字节,但如今大多数操作系统的IO 电梯、预取和设备端缓冲区都阻止了这种情况(但它以大批量顺序读取总是更好)。
如果您myParser.Parse(instrm)
使用bufio.Reader
4K的默认缓冲区进行调用,您将导致 1,024 次上下文切换(每个系统调用读取 4K 而不是 1 个字节)。由于每个系统调用都有一些开销,这意味着花在系统调用上的时间更少,程序运行的时间更多。还值得指出的是,以这种方式运行(没有额外的上下文切换)通常会增加CPU 指令缓存命中率,因为将花费更多时间在较小的内存区域内进行分支。
缓冲区在网络 IO 等领域甚至很重要,因为它允许您以最大MTU大小发送突发数据包,而不是发送细小的数据包。
只是不要忘记刷新您的写入缓冲区。
- 1 回答
- 0 关注
- 288 浏览
添加回答
举报
0/150
提交
取消