比 Python 慢?
Go slower than Python?
我有以下 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")
}
}
正如 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
还应注意,就性能比较而言,这不是一个好案例。它并不代表真实的应用程序会做什么,以某种方式处理数据。
我有以下 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")
}
}
正如 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
还应注意,就性能比较而言,这不是一个好案例。它并不代表真实的应用程序会做什么,以某种方式处理数据。