go语言 替换字符串中的空格 多种方法性能比较

经过优化,速度提升了一倍,内存申请降低了36倍

package main

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

func BenchmarkA(b *testing.B) {
    s := "(英语:Arabic language;阿拉伯语:لغة عربية;拉丁转写: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;阿拉伯语:لغة عربية;拉丁转写: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;阿拉伯语:لغة عربية;拉丁转写: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;阿拉伯语:لغة عربية;拉丁转写: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

你可能感兴趣的:(go语言 替换字符串中的空格 多种方法性能比较)