go語言 替換字符串中的空格 多種方法性能比較

經(jīng)過優(yōu)化,速度提升了一倍,內(nèi)存申請降低了36倍

package main

import (
    "sync"
    "testing"
    "unicode"
    "unsafe"
)

func BenchmarkA(b *testing.B) {
    s := "(英語:Arabic language;阿拉伯語:??? ?????;拉丁轉(zhuǎn)寫:lughatu ?arabīyatu;IPA注音:/??l?lu?ɑt?u ??l?ɑr?bi?jat?u/)"
    for i := 0; i < b.N; i++ {
        var ru []rune
        for _, r := range s {
            if unicode.IsPunct(r) {
                ru = append(ru, ' ')
            } else {
                ru = append(ru, r)
            }
        }
        _ = string(ru)
    }
}

func BenchmarkB(b *testing.B) {
    s := "(英語:Arabic language;阿拉伯語:??? ?????;拉丁轉(zhuǎn)寫:lughatu ?arabīyatu;IPA注音:/??l?lu?ɑt?u ??l?ɑr?bi?jat?u/)"
    for i := 0; i < b.N; i++ {
        ru := []rune(s)
        for j := range ru {
            if unicode.IsPunct(ru[j]) {
                ru[j] = ' '
            }
        }
        _ = string(ru)
    }
}

var runePool = &sync.Pool{New: func() interface{} { return make([]rune, 0, 8) }}

func BenchmarkC(b *testing.B) {
    s := "(英語:Arabic language;阿拉伯語:??? ?????;拉丁轉(zhuǎn)寫:lughatu ?arabīyatu;IPA注音:/??l?lu?ɑt?u ??l?ɑr?bi?jat?u/)"
    for i := 0; i < b.N; i++ {
        ru := runePool.Get().([]rune)
        for _, r := range s {
            if unicode.IsPunct(r) {
                ru = append(ru, ' ')
            } else {
                ru = append(ru, r)
            }
        }
        runePool.Put(ru[:0])
        _ = string(ru)
    }
}

var bytePool = &sync.Pool{New: func() interface{} { return make([]byte, 0, 24) }}

const (
    MaxASCII     = '\u007F'
    Max2byteRune = '\u07FF'
    Max3byteRune = '\uFFFF'
    MaxRune      = '\U0010FFFF'
)

func BenchmarkD(b *testing.B) {
    s := "(英語:Arabic language;阿拉伯語:??? ?????;拉丁轉(zhuǎn)寫:lughatu ?arabīyatu;IPA注音:/??l?lu?ɑt?u ??l?ɑr?bi?jat?u/)"
    for i := 0; i < b.N; i++ {

        bb := bytePool.Get().([]byte)
        for j, r := range s {
            if unicode.IsPunct(r) {
                bb = append(bb, ' ')
            } else {
                switch {
                case r <= MaxASCII:
                    bb = append(bb, s[j])
                case r <= Max2byteRune:
                    bb = append(bb, s[j:j+2]...)
                case r <= Max3byteRune:
                    bb = append(bb, s[j:j+3]...)
                case r <= MaxRune:
                    bb = append(bb, s[j:j+4]...)
                }
            }
        }

        bytePool.Put(bb[:0])
        _ = b2s(bb)
    }
}

func b2s(b []byte) string {
    return *(*string)(unsafe.Pointer(&b))
}

?   go test -bench=. -benchmem -run=none
goos: darwin
goarch: amd64
pkg: LearnAndTest/learn_test
BenchmarkA-8      551626              2056 ns/op            1176 B/op          8 allocs/op
BenchmarkB-8      611943              2000 ns/op             544 B/op          2 allocs/op
BenchmarkC-8      735289              1650 ns/op             192 B/op          2 allocs/op
BenchmarkD-8     1216750               996 ns/op              32 B/op          1 allocs/op
PASS
ok      LearnAndTest/learn_test 5.850s

最后編輯于
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容