为什么Go的字符串。字段(str)和strings.Split(str,"")这么慢?

时间:2017-05-29 14:14:05

标签: arrays node.js string performance go

我一直在测试Node和Go中的功能来比较它们的性能。在几乎每个测试中,Go都比Node快得多,除非使用strings.Fields()strings.Split(),那么Node的速度要快2-3倍。

Go(2.14s):

start := time.Now()
var newWords []string
str := "asd asjhfa lsjdhalsdjhfa dhfald hfaljdh faldhfasjdhfalsdh asd alsdh alksdh alksdh alksd alkjsd fadlkj dalkjdh asdhfef afa d6a 5a85dfa s5da5d ad a6sd58ad5a8sd5f 8as5f as5 a8s5 8as6d5 8asd65f8as6d58 a5sd 8a5ds8f7 a6s5d"

for j := 0; j < 1000000; j++ {
    words := strings.Split(str, " ")
    wordsLen := len(words)
    newWords = nil
    for i := 0; i < wordsLen; i++ {
        if words[i][:1] != "s" {
            newWords = append(newWords, words[i])
        }
    }
}
dur := time.Since(start)

fmt.Println(newWords)
fmt.Println(dur)

节点(847ms):

let start = new Date()
let newWords = []
let str = "asd asjhfa lsjdhalsdjhfa dhfald hfaljdh faldhfasjdhfalsdh asd alsdh alksdh alksdh alksd alkjsd fadlkj dalkjdh asdhfef afa d6a 5a85dfa s5da5d ad a6sd58ad5a8sd5f 8as5f as5 a8s5 8as6d5 8asd65f8as6d58 a5sd 8a5ds8f7 a6s5d"

for (let j = 0; j < 1000000; j++) {
    let words = str.split(' ')
    let wordsLen = words.length
    newWords = []
    for (let i = wordsLen - 1; i >= 0; i--) {
        if (words[i].substr(0, 1) !== 's') {
            newWords.push(words[i])
        }
    }
}

console.log((new Date() - start) + 'ms')

1 个答案:

答案 0 :(得分:1)

首先,让我们进行测试。

$ go run travis.go
5.892531292s
$ node travis.js
4065ms
$

5.8秒,而Node.js则为4.07秒。

其次,让我们运行一个Go基准测试,看看你到底在做什么。它比您在原帖中所说的strings.Fields(str)strings.Split(str, " ")要多得多。

travis_test.go

package main

import (
    "strings"
    "testing"
)

var str = "asd asjhfa lsjdhalsdjhfa dhfald hfaljdh faldhfasjdhfalsdh asd alsdh alksdh alksdh alksd alkjsd fadlkj dalkjdh asdhfef afa d6a 5a85dfa s5da5d ad a6sd58ad5a8sd5f 8as5f as5 a8s5 8as6d5 8asd65f8as6d58 a5sd 8a5ds8f7 a6s5d"

func Travis() {
    var newWords []string
    for j := 0; j < 1000000; j++ {
        words := strings.Split(str, " ")
        wordsLen := len(words)
        newWords = nil
        for i := 0; i < wordsLen; i++ {
            if words[i][:1] != "s" {
                newWords = append(newWords, words[i])
            }
        }
    }
}

func BenchmarkTravis(b *testing.B) {
    b.ReportAllocs()
    b.ResetTimer()
    for i := 0; i < b.N; i++ {
        Travis()
    }
    b.StopTimer()
}

输出:

$ go test -run=! -bench=Travis travis_test.go 
goos: linux
goarch: amd64
BenchmarkTravis-4   1   5832192616 ns/op   1488002816 B/op   7000015 allocs/op
PASS
ok      command-line-arguments  5.838s
$