比Python慢​​?

时间:2015-01-15 16:06:57

标签: python performance go

我有以下Go代码:

package main

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

func main() {
    reader := bufio.NewReader(os.Stdin)
    scanner := bufio.NewScanner(reader)

    for scanner.Scan() {
        fmt.Println(scanner.Text())
    }
}

以及以下Python代码:

import sys

for ln in sys.stdin:
    print ln,

两者都只是从标准输入读取行并打印到标准输出。 Python版本仅使用Go版本所需时间的1/4(在1600万行文本文件上测试并输出到/ dev / null)。那是为什么?

更新:在JimB和siritinga的建议之后,我将Go的输出更改为缓冲版本。现在Go版本要快得多,但仍然比Python版本慢75%。

package main

import ("os"
        "bufio")

func main() {
    reader := bufio.NewReader(os.Stdin)
    scanner := bufio.NewScanner(reader)
    writer := bufio.NewWriter(os.Stdout)

    for scanner.Scan() {
        writer.WriteString(scanner.Text()+"\n")
    }
}

1 个答案:

答案 0 :(得分:3)

正如JimB所说,停止使用字符串。 Python 2.x字符串只是原始字节。 Go字符串是UTF-8。这需要编码,检查错误等。另一方面,您还可以从字符串中获得更多功能。此外,构建字符串需要额外的内存分配。

如果您使用Python实现更改为unicode字符串(升级到3.x或2.x的unicode字符串实现),性能将会变为坦克。如果您使用Go版本更改为类似的编码,您将获得更好的性能:

package main

import ("os"
        "bufio")

func main() {
    reader := bufio.NewReader(os.Stdin)
    scanner := bufio.NewScanner(reader)
    writer := bufio.NewWriter(os.Stdout)
    newline := []byte("\n")

    for scanner.Scan() {
        writer.Write(scanner.Bytes())
        writer.Write(newline)
    }
}

在我的系统上,使用包含6500万行的单词列表,Python:

real    0m12.724s
user    0m12.581s
sys     0m0.145s

Go版本:

real    0m4.408s
user    0m4.276s
sys     0m0.135s

还应该注意的是,就性能比较而言,这是一个好的案例。它并不代表真正的应用程序会做什么,以某种方式处理数据。