0

0

为什么 Go 中读写文件比 Perl 慢很多?

王林

王林

发布时间:2024-02-09 21:30:24

|

1010人浏览过

|

来源于stackoverflow

转载

为什么 go 中读写文件比 perl 慢很多?

为什么 Go 中读写文件比 Perl 慢很多?这是很多开发者在使用这两种编程语言时经常遇到的问题。在这篇文章中,php小编草莓将为您解答这个问题。在比较 Go 和 Perl 读写文件的速度时,我们需要考虑到两个关键因素:语言特性和底层实现。Go 语言在文件读写方面的设计理念与 Perl 不同,这导致了它们在性能上的差异。同时,底层实现也是影响读写速度的重要因素。接下来,我们将详细分析这些因素,帮助您更好地理解为什么 Go 中读写文件比 Perl 慢很多。

问题内容

我使用go是为了提高代码效率,但是当我使用go读写文件时,发现它的读写效率没有perl高。是我代码的问题还是其他原因?

构建输入文件:

# input file:
for i in $(seq 1 600000) do     echo server$((random%800+100)),$random,$random,$random >> sample.csv done

用perl读写文件:

time cat sample.csv | perl -ne 'chomp;print"$_"' > out.txt
real    0m0.249s
user    0m0.083s
sys 0m0.049s

使用 go 读写文件:

package main

import (
    "bufio"
    "fmt"
    "io"
    "os"
    "strings"
)

func main() {

    filepath := "./sample.csv"
    file, err := os.openfile(filepath, os.o_rdwr, 0666)
    if err != nil {
        fmt.println("open file error!", err)
        return
    }
    defer file.close()
    buf := bufio.newreader(file)
    for {
        line, err := buf.readstring('\n')
        line = strings.trimspace(line)
        fmt.println(line)
        if err != nil {
            if err == io.eof {
                fmt.println("file read ok!")
                break
            } else {
                fmt.println("read file error!", err)
                return
            }
        }
    }
}

然后我运行:

time go run read.go > out.txt
real    0m2.332s
user    0m0.326s
sys 0m2.038s

为什么 go 的读写速度比 perl 慢近 10 倍?

解决方法

您正在将苹果与橙子进行比较。

至少有两个方法错误:

  1. 您的 perl 咒语测量 cat 如何读取文件并通过 pipe(2) 发送其内容,而 pipe(2) 发送其内容 从那里读取数据,对其进行处理并将结果写入其标准输出。

  2. 你的围棋咒语

    • 测量 go 工具链的完整构建过程(包括编译、链接和写出可执行映像文件)然后运行 已编译程序的组成部分,以及
    • 测量对标准输出的无缓冲写入(perl 调用),而在 perl 代码中写入标准输出 - 引用 文档 - “如果输出到终端,通常可以进行行缓冲,否则进行块缓冲。”

让我们尝试比较一下苹果。

首先,这是一个类似的 go 实现:

package main

import (
    "bufio"
    "bytes"
    "fmt"
    "os"
)

func main() {
    in := bufio.newscanner(os.stdin)
    out := bufio.newwriter(os.stdout)

    for in.scan() {
        s := bytes.trimspace(in.bytes())

        if _, err := out.write(s); err != nil {
            fmt.fprint(os.stderr, "failed to write file:", err)
            os.exit(1)
        }
    }

    if err := out.flush(); err != nil {
        fmt.fprint(os.stderr, "failed to write file:", err)
        os.exit(1)
    }

    if err := in.err(); err != nil {
        fmt.fprint(os.stderr, "reading failed:", err)
        os.exit(1)
    }
}

让我们将其保存为 fmt.print* 并进行测量:

  1. 构建代码:

    Quillbot
    Quillbot

    一款AI写作润色工具,QuillBot的人工智能改写工具将提高你的写作能力。

    下载

    chomp.go

  2. 生成输入文件:

    $ go build chomp.go

  3. 运行 perl 代码:

    $ time { perl -ne 'chomp; print "$_";' out1.txt; }
    
    real    0m0.226s
    user    0m0.102s
    sys 0m0.048s
  4. 再次运行它以确保它已从文件系统缓存中读取输入文件:

    $ time { perl -ne 'chomp; print "$_";' out1.txt; }
    
    real   0m0.123s
    user   0m0.090s
    sys    0m0.033s

    注意执行时间是如何减少的。

  5. 在缓存的输入上运行 go 代码:

    $ time { ./chomp out2.txt; }
    
    real   0m0.063s
    user   0m0.032s
    sys    0m0.032s
  6. 确保结果相同:

    $ for i in $(seq 1 600000);执行 echo server$((random%800+100)),$random,$random,$random;完成 >sample.csv

如您所见,在我的带有 ssd 的 $ cmp out1.txt out2.txt 系统上,结果大致相同。

嗯,我还应该指出,为了获得合理的结果,您需要运行每个命令,例如 1000 次,并对每个批次中的结果进行平均,然后比较这些数字,但我认为这足以证明什么您的方法存在的问题是。

还有一件事需要考虑:这两个程序的运行时间绝大多数由文件系统 i/o 主导,因此,如果您认为 go 会更快,那么您的期望是没有根据的:这两个程序大部分时间sleep 在内核的系统调用 read(2)write(2)。在某些涉及 cpu 运算的情况下,go 程序可能比 perl 程序更快(特别是如果它是为利用多核系统而编写的),但您的示例根本不是这种情况。

哦,只是为了明确未说明的事实:虽然 go 语言规范没有说明 aot,而 linux/amd64 是一种针对一次性一次性演出的 hack,严肃的工作,也不执行任何严重复杂程度的代码。简而言之,go-that-you-are-using 并不是一种解释性语言,尽管 read(2) 的可用性可能使它看起来如此。事实上,它执行正常 write(2) 会执行的操作,然后运行生成的可执行文件,然后将其丢弃。

您可能会想说 perl 也处理“源代码”,但 perl 解释器针对处理脚本和 go 的构建工具链进行了高度优化——同时与大多数其他编译语言相比速度快得惊人——未针对此进行优化。
可能更明显的区别是,perl 解释器实际上解释您的(非常简单的)脚本,而 go rungo run 是所谓的“内置函数”,很容易提供给由解释器执行脚本。与构建 go 程序相比,编译器解析源代码文件并将其转换为机器代码,链接器实际上读取 go 标准库的编译包的文件 - 所有这些都是 go builded, - 从它们,组合所有这些机器代码并写出一个可执行图像文件(这很像 chomp 二进制文件本身!);当然,这是一个非常消耗资源的过程,与实际的程序执行无关。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
python中print函数的用法
python中print函数的用法

python中print函数的语法是“print(value1, value2, ..., sep=' ', end=' ', file=sys.stdout, flush=False)”。本专题为大家提供print相关的文章、下载、课程内容,供大家免费下载体验。

186

2023.09.27

java入门学习合集
java入门学习合集

本专题整合了java入门学习指南、初学者项目实战、入门到精通等等内容,阅读专题下面的文章了解更多详细学习方法。

2

2026.01.29

java配置环境变量教程合集
java配置环境变量教程合集

本专题整合了java配置环境变量设置、步骤、安装jdk、避免冲突等等相关内容,阅读专题下面的文章了解更多详细操作。

2

2026.01.29

java成品学习网站推荐大全
java成品学习网站推荐大全

本专题整合了java成品网站、在线成品网站源码、源码入口等等相关内容,阅读专题下面的文章了解更多详细推荐内容。

0

2026.01.29

Java字符串处理使用教程合集
Java字符串处理使用教程合集

本专题整合了Java字符串截取、处理、使用、实战等等教程内容,阅读专题下面的文章了解详细操作教程。

0

2026.01.29

Java空对象相关教程合集
Java空对象相关教程合集

本专题整合了Java空对象相关教程,阅读专题下面的文章了解更多详细内容。

3

2026.01.29

clawdbot ai使用教程 保姆级clawdbot部署安装手册
clawdbot ai使用教程 保姆级clawdbot部署安装手册

Clawdbot是一个“有灵魂”的AI助手,可以帮用户清空收件箱、发送电子邮件、管理日历、办理航班值机等等,并且可以接入用户常用的任何聊天APP,所有的操作均可通过WhatsApp、Telegram等平台完成,用户只需通过对话,就能操控设备自动执行各类任务。

25

2026.01.29

clawdbot龙虾机器人官网入口 clawdbot ai官方网站地址
clawdbot龙虾机器人官网入口 clawdbot ai官方网站地址

clawdbot龙虾机器人官网入口:https://clawd.bot/,clawdbot ai是一个“有灵魂”的AI助手,可以帮用户清空收件箱、发送电子邮件、管理日历、办理航班值机等等,并且可以接入用户常用的任何聊天APP,所有的操作均可通过WhatsApp、Telegram等平台完成,用户只需通过对话,就能操控设备自动执行各类任务。

16

2026.01.29

Golang 网络安全与加密实战
Golang 网络安全与加密实战

本专题系统讲解 Golang 在网络安全与加密技术中的应用,包括对称加密与非对称加密(AES、RSA)、哈希与数字签名、JWT身份认证、SSL/TLS 安全通信、常见网络攻击防范(如SQL注入、XSS、CSRF)及其防护措施。通过实战案例,帮助学习者掌握 如何使用 Go 语言保障网络通信的安全性,保护用户数据与隐私。

8

2026.01.29

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
SQL 教程
SQL 教程

共61课时 | 3.6万人学习

PHP面向对象基础课程(更新中)
PHP面向对象基础课程(更新中)

共12课时 | 0.7万人学习

FastAPI框架精讲课程
FastAPI框架精讲课程

共38课时 | 2.5万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号