博客
关于我
70 行 Go 代码打败 C!
阅读量:567 次
发布时间:2019-03-09

本文共 2799 字,大约阅读时间需要 9 分钟。

用Go语言编写高效的wc命令

作为一名程序员,挑战编写高性能的wc命令总是很有趣的。这次,我们将用Go语言来实现一个高效的wc命令,挑战传统的C语言实现。

背景

Chris Penner最近发布了一篇文章,展示了如何用80行Haskell代码击败C语言版wc命令(https://chrispenner.ca/posts/wc)。这引发了广泛讨论,许多开发者开始尝试用其他语言实现wc命令。以下是一些值得挑战的语言:

  • Ada
  • C
  • Common Lisp
  • Dyalog APL
  • Futhark
  • Haskell
  • Rust
  • 今天,我们将用Go语言来实现这一挑战。作为一种支持并发原语的编译语言,Go语言有望轻松匹配C语言的性能。

    实现思路

    虽然wc命令的设计目标是从标准输入读取文本、处理空白字符和解析命令行参数,但我们将简化实现,专注于核心逻辑。具体来说,我们将:

  • 读取文件路径和文件内容
  • 统计行数、单词数和字节数
  • 使用简单的状态机来跟踪空白字符
  • 基准测试

    为了比较Go语言和C语言版本的wc命令,我们将使用GNU的time工具包,分别从运行时间和内存使用两个方面进行评估。以下是测试基准:

    • 处理器:Intel酷睿i5-6200U(2个物理核,4个线程)
    • 内存:4+4 GB @ 2133 MHz
    • 存储:240 GB M.2固态硬盘
    • 操作系统:Fedora 31 Linux

    简单实现

    我们的Go实现将直接从文件中读取字节,并使用简单的状态机来跟踪空白字符。具体代码如下:

    const bufferSize = 16 * 1024reader := bufio.NewReaderSize(file, bufferSize)lineCount, wordCount, byteCount := 0, 0, 0prevByteIsSpace := truefor {    b, err := reader.ReadByte()    if err == os.EOF {        break    }    byteCount++    switch {    case '\n':        lineCount++        prevByteIsSpace = true    case ' ', '\t', '\r', '\v', '\f':        prevByteIsSpace = true    default:        if prevByteIsSpace {            wordCount++            prevByteIsSpace = false        }    }}

    优势分析

    • 内存使用:Go语言的内存使用效率远高于C语言。
    • 性能:在我们的初步测试中,Go实现的运行时间接近C语言版本。

    优化与改进

    为了进一步提升性能,我们可以采取以下优化措施:

  • 缓冲读取

    将输入分成多个缓冲块(chunk),并使用并发处理来提高读取效率。

  • 并行化处理

    利用Go语言的并发原语,将文件读取和统计分配给多个 goroutine,提升整体处理速度。

  • 内存管理

    使用 bufio.ReaderSize 来优化缓冲读取,减少内存分配和释放的开销。

  • 并行化实现

    为了实现并行化,我们可以创建一个 Chunk 结构,存储每个缓冲块的信息。然后,将输入分配给多个 goroutine进行处理:

    type Chunk struct {    PrevCharIsSpace bool    Buffer []byte}func GetCount(chunk Chunk) (line, word int) {    line := 1    word := 1    prevIsSpace := chunk.PrevCharIsSpace    for _, b := range chunk.Buffer {        switch b {        case '\n':            line++            prevIsSpace = true        case ' ', '\t', '\r', '\v', '\f':            prevIsSpace = true        default:            if prevIsSpace {                word++                prevIsSpace = false            }        }    }    return line, word}func main() {    numWorkers := runtime.NumCPU()    chunks := make(chan Chunk)    counts := make(chan Count)    for i := 0; i < numWorkers; i++ {        go ChunkCounter(chunks, counts)    }    buffer := make([]byte, bufferSize)    lastCharIsSpace := true    for {        bytes, err := file.Read(buffer)        if err == os.EOF {            break        }        chunk := Chunk{            PrevCharIsSpace: lastCharIsSpace,            Buffer: buffer[:bytes],        }        chunks <- chunk        lastCharIsSpace = IsSpace(buffer[bytes-1])    }    close(chunks)    for i := 0; i < numWorkers; i++ {        count := <-counts        total.LineCount += count.Line        total.WordCount += count.Word    }    close(counts)}

    性能评估

    • 运行时间:并行化实现的运行时间显著降低,甚至超过了C语言版本。
    • 内存使用:并行化虽然提升了性能,但也增加了内存消耗。

    最终总结

    虽然本文并未暗示Go语言比C语言更强,但我们希望通过这一实现展示Go语言在系统编程方面的潜力。

    如果你对本文有任何建议或疑问,欢迎在评论区留言。

    转载地址:http://bfqpz.baihongyu.com/

    你可能感兴趣的文章
    OpenCV与AI深度学习 | YOLOv8重磅升级,新增旋转目标检测,又该学习了!
    查看>>
    OpenCV与AI深度学习 | 一文带你读懂YOLOv1~YOLOv11(建议收藏!)
    查看>>
    OpenCV与AI深度学习 | 五分钟快速搭建一个实时人脸口罩检测系统(OpenCV+PaddleHub 含源码)
    查看>>
    OpenCV与AI深度学习 | 什么是 COCO 数据集?
    查看>>
    OpenCV与AI深度学习 | 低对比度缺陷检测应用实例--LCD屏幕脏污检测
    查看>>
    OpenCV与AI深度学习 | 使用 MoveNet Lightning 和 OpenCV 实现实时姿势检测
    查看>>
    OpenCV与AI深度学习 | 使用 OpenCV 创建自定义图像滤镜
    查看>>
    OpenCV与AI深度学习 | 使用 SAM 和 Grounding DINO 分割卫星图像
    查看>>
    OpenCV与AI深度学习 | 使用OpenCV图像修复技术去除眩光
    查看>>
    OpenCV与AI深度学习 | 使用OpenCV检测并计算直线角度
    查看>>
    OpenCV与AI深度学习 | 使用OpenCV轮廓检测提取图像前景
    查看>>
    OpenCV与AI深度学习 | 使用Python和OpenCV实现火焰检测(附源码)
    查看>>
    OpenCV与AI深度学习 | 使用PyTorch进行小样本学习的图像分类
    查看>>
    OpenCV与AI深度学习 | 使用YOLO11实现区域内目标跟踪
    查看>>
    OpenCV与AI深度学习 | 使用YOLOv8做目标检测、实例分割和图像分类(包含实例操作代码)
    查看>>
    OpenCV与AI深度学习 | 使用单相机对已知物体进行3D位置估计
    查看>>
    OpenCV与AI深度学习 | 初学者指南 -- 什么是迁移学习?
    查看>>
    OpenCV与AI深度学习 | 十分钟掌握Pytorch搭建神经网络的流程
    查看>>
    OpenCV与AI深度学习 | 基于GAN的零缺陷样本产品表面缺陷检测
    查看>>
    OpenCV与AI深度学习 | 基于OpenCV和深度学习预测年龄和性别
    查看>>