- r - 以节省内存的方式增长 data.frame
- ruby-on-rails - ruby/ruby on rails 内存泄漏检测
- android - 无法解析导入android.support.v7.app
- UNIX 域套接字与共享内存(映射文件)
在提供读取随机生成的输入文件并将读取的相同字符串回显到输出的相同程序之后。唯一的区别是,一方面我提供来自 linux 系统调用的读写方法,另一方面我使用 fread/fwrite。
用 10Mb 大小的输入为我的应用程序计时,并将其回显到/dev/null,并确保该文件未被缓存,我发现当使用非常小的缓冲区时,libc 的 fwrite 速度大大加快( 1 个字节以防万一)。
这是我使用 fwrite 时的输出:
real 0m0.948s
user 0m0.780s
sys 0m0.012s
并使用系统调用写入:
real 0m8.607s
user 0m0.972s
sys 0m7.624s
我能想到的唯一可能性是内部 libc 已经在缓冲我的输入...不幸的是我在网上找不到那么多信息,所以也许这里的专家可以帮助我。
最佳答案
Timing my application with an input of 10Mb in size and echoing it to /dev/null, and making sure the file in not cached, I've found that libc's frwite is faster by a LARGE scale when using very small buffers (1 byte in case).
fwrite
适用于缓冲的流。因此,许多小缓冲区会更快,因为它不会运行昂贵的系统调用,直到缓冲区填满(或者您刷新它或关闭流)。另一方面,发送到 write
的小缓冲区将对每个缓冲区 运行代价高昂的系统调用 - 这就是您失去速度的地方。对于 1024 字节的流缓冲区和写入 1 字节的缓冲区,您将看到每 千字节 有 1024 次 write
调用,而不是 1024 次 fwrite
调用变成一个write
- 看到区别了吗?
对于大缓冲区,差异会很小,因为缓冲会更少,因此 fwrite
和 write
之间的系统调用数量会更一致。
换句话说,fwrite(3)
只是一个库例程,它将输出收集到 block 中,然后调用 write(2)
。现在,write(2)
是一个系统调用,它陷入内核。这就是 I/O 实际发生的地方。简单地调用内核会有一些开销,然后实际编写一些东西需要时间。如果您使用大缓冲区,您会发现 write(2)
更快,因为无论如何最终都必须调用它,并且如果您每次 fwrite 写入一次或多次,那么 fwrite 缓冲开销只是那:更多的开销。
如果您想阅读更多相关信息,可以查看this document。 ,其中解释了标准 I/O 流。
关于c - 为什么 fwrite libc 函数比 syscall write 函数快?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1360021/
我正在阅读 syscall 包中的源代码,遇到了一些问题: 因为我对syscall 和assembly 完全是个菜鸟,所以不要犹豫,分享你所知道的一切:) 首先关于 func RawSyscall(t
我在一台机器上运行Docker镜像时看到以下错误 uname -r 3.10.0-229.7.2.el7.x86_64 2016/11/01 23:46:56 Error resolving sysc
不推荐使用 syscall 软件包。假设我有以下代码,希望将其迁移到不推荐使用的代码中: someGoObject := &struct{int; float32}{5, 45.4} syscall.
我正在尝试使用 VkKeyScan来自 Window 的 API,但是只要调用该函数,程序就会崩溃。我以这种方式导入和使用的其他 Window API 函数没有问题。我的 syscall.Syscal
在研究我的另一个问题时Go package syscall conn.Read() is non-blocking and cause high CPU usage , 我阅读了 syscall 包中
在 Windows 上使用 go 我有一个名为 sock 的 syscall.Handle,我想将其绑定(bind)到名为“sa”的 syscall.Sockaddr 结构中指定的地址。 如何填写 s
谁能告诉我为什么 syscall.Kill(pid, syscall.SIGSEGV) 只打印一次 "handlerSIGSEGV Sent by 0" ,但是 mustSendSIGSEGV 会打印
当我尝试在 Ubuntu 机器中启用 PPP 时,在 menuconfig 之后发生以下错误并尝试制作内核: $ sudo make make[1]: *** No rule to make targ
当我尝试在 Ubuntu 机器中启用 PPP 时,在 menuconfig 和尝试制作内核之后发生了以下错误: $ sudo make make[1]: *** No rule to make tar
我一直在尝试Go和Win32,发现了用于调用OS函数的以下两种变体(代码缩写): modUser32 = syscall.NewLazyDLL("user32.dll") procMessageBox
源代码是here 我对我的理解发表了评论 type mmapper struct { sync.Mutex active map[*byte][]byte // active mapp
这个问题在这里已经有了答案: What does a function without body mean? (1 个回答) 3年前关闭。 谁能解释一下 Go 标准库中 syscall 包中的以下代码
我目前正在尝试在 Go 上使用 user32.dll EnumWindows,但似乎无法正常工作 var( user32 = syscall.NewLazyDLL("user32.dll")
我的代码包括对 _write() 和 _sbrk() 等函数的间接调用。在项目中,我有一个名为 syscalls.c 的文件,它定义了我对这些函数的自定义实现,编译器/链接器找到了这个文件,并在我运行
我是新来的,目前正在尝试了解同事编写的一些代码 go func() { s := <-sigs if s == syscall.SIGURG { fmt.Println
我试图了解Golangs syscall软件包的一些底层细节。特别是,我对特定于Windows的系统调用感兴趣(请参见下面的示例)。 我可以找到基于UNIX的系统的syscall.Syscall()的
我有两个运行的过程,用Go语言编写,其中一个(sender.go)将消息发送到另一个(listener.go),同时通过websocket陷入for循环中。 问题是listener.go仅在终止循环后
有syscall它允许在 Linux 中进行间接系统调用。使用它的原因是什么 - 为什么它比直接调用函数更好? 最佳答案 有时内核会添加系统调用,C 库需要一段时间才能支持它们。 或者您可能正在旧的
您好 使用tkill() linux 内核调用向进程的每个线程发送信号 是否安全?因为它没有直接公开,所以我使用 syscall() 调用它。 我指的是链接 - . 但我不知道我是否应该在调用之前进行
当我创建模块时,它会发出此警告,并且会构建稍后的模块。但是如果没有实现我自己的系统调用“mycall”,构建模块有什么用 root@akshit-Vostro-1550:~/Desktop/Devic
我是一名优秀的程序员,十分优秀!