How to replace a letter at a specific index in a string in Go?

huangapple go评论91阅读模式
英文:

How to replace a letter at a specific index in a string in Go?

问题

我想在字符串的特定索引处替换一个字母:aaaaaaa -> aaabaaa。有没有内置的方法可以做到这一点?我写了下面的辅助函数来临时使用:

func main() {
    input := "aaaaaaa"
    output := replaceAtIndex(input, 'b', 3)
}

func replaceAtIndex(input string, replacement byte, index int) string {
    return strings.Join([]string{input[:index], string(replacement), input[index+1:]}, "")
}

这个函数会将输入字符串在指定索引处的字母替换为指定的字母,并返回替换后的字符串。

英文:

I want to replace a letter at a specific index in a string: aaaaaaa -> aaabaaa. Is there a built in way to do this? I wrote the following helper function to use in the mean time:

func main() {
    input := "aaaaaaa"
    output := replaceAtIndex(input, 'b', 3)
}

func replaceAtIndex(input string, replacement byte, index int) string {
    return strings.Join([]string{input[:index], string(replacement), input[index+1:]}, "")
}

答案1

得分: 41

在Go语言中,字符串是不可变的,你需要将其转换为符文(rune),然后修改它,最后再将其转换回字符串。

@chendesheng的解决方案基本正确,只是你可以使用rune而不是byte,这样它也可以在Unicode上工作。

func replaceAtIndex(in string, r rune, i int) string {
    out := []rune(in)
    out[i] = r
    return string(out)
}

playground

英文:

Strings are immutable in Go, you have to convert it to runes then modify it then convert it back to a string.

@chendesheng's solution is semi-correct, except you can use rune instead of byte, that way it will work on unicode as well.

func replaceAtIndex(in string, r rune, i int) string {
	out := []rune(in)
	out[i] = r
	return string(out)
}

<kbd>playground</kbd>

答案2

得分: 29

两个答案(OneOfOneDenys Séguret)都是正确的。我只是想展示它们之间的性能差异(当字符串很大时,这种差异非常明显)。

结果表明,使用**str[:index] + string(replacement) + str[index+1:]**的速度更快。

所以进行基准测试的代码如下:

package main
import (
	"testing"
)

func replaceAtIndex1(str string, replacement rune, index int) string {
	out := []rune(str)
	out[index] = replacement
	return string(out)
}

func replaceAtIndex2(str string, replacement rune, index int) string {
	return str[:index] + string(replacement) + str[index+1:]
}

func generateString(n int) string{
	s := ""
	for i := 0; i < n; i++{
		s += "a"
	}
	return s
}

func BenchmarkSmall1(b *testing.B) {
	n := 10
	str, index, replacement := generateString(n), n / 2, 'B'

	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		replaceAtIndex1(str, replacement, index)
	}
}

func BenchmarkSmall2(b *testing.B) {
	n := 10
	str, index, replacement := generateString(n), n / 2, 'B'

	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		replaceAtIndex2(str, replacement, index)
	}
}

func BenchmarkMedium1(b *testing.B) {
	n := 100
	str, index, replacement := generateString(n), n / 2, 'B'

	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		replaceAtIndex1(str, replacement, index)
	}
}

func BenchmarkMedium2(b *testing.B) {
	n := 100
	str, index, replacement := generateString(n), n / 2, 'B'

	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		replaceAtIndex2(str, replacement, index)
	}
}

func BenchmarkBig1(b *testing.B) {
	n := 10000
	str, index, replacement := generateString(n), n / 2, 'B'

	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		replaceAtIndex1(str, replacement, index)
	}
}

func BenchmarkBig2(b *testing.B) {
	n := 10000
	str, index, replacement := generateString(n), n / 2, 'B'

	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		replaceAtIndex2(str, replacement, index)
	}
}

func main(){}

下面是基准测试的结果(感谢Thomasz发现了一个复制粘贴错误):


BenchmarkSmall1-4 	10000000	       228 ns/op
BenchmarkSmall2-4 	10000000	       126 ns/op
BenchmarkMedium1-4	  500000	      2091 ns/op
BenchmarkMedium2-4	10000000	       190 ns/op
BenchmarkBig1-4   	   10000	    209232 ns/op
BenchmarkBig2-4   	  500000	      3629 ns/op
英文:

Both of the answers (OneOfOne and Denys Séguret) are correct. I just wanted to show the performance difference between them (which is really noticeable when the string is big).

It turns out that using str[:index] + string(replacement) + str[index+1:] is way faster.

So the benchmark:

package main
import (
&quot;testing&quot;
)
func replaceAtIndex1(str string, replacement rune, index int) string {
out := []rune(str)
out[index] = replacement
return string(out)
}
func replaceAtIndex2(str string, replacement rune, index int) string {
return str[:index] + string(replacement) + str[index+1:]
}
func generateString(n int) string{
s := &quot;&quot;
for i := 0; i &lt; n; i++{
s += &quot;a&quot;
}
return s
}
func BenchmarkSmall1(b *testing.B) {
n := 10
str, index, replacement := generateString(n), n / 2, &#39;B&#39;
b.ResetTimer()
for i := 0; i &lt; b.N; i++ {
replaceAtIndex1(str, replacement, index)
}
}
func BenchmarkSmall2(b *testing.B) {
n := 10
str, index, replacement := generateString(n), n / 2, &#39;B&#39;
b.ResetTimer()
for i := 0; i &lt; b.N; i++ {
replaceAtIndex2(str, replacement, index)
}
}
func BenchmarkMedium1(b *testing.B) {
n := 100
str, index, replacement := generateString(n), n / 2, &#39;B&#39;
b.ResetTimer()
for i := 0; i &lt; b.N; i++ {
replaceAtIndex1(str, replacement, index)
}
}
func BenchmarkMedium2(b *testing.B) {
n := 100
str, index, replacement := generateString(n), n / 2, &#39;B&#39;
b.ResetTimer()
for i := 0; i &lt; b.N; i++ {
replaceAtIndex2(str, replacement, index)
}
}
func BenchmarkBig1(b *testing.B) {
n := 10000
str, index, replacement := generateString(n), n / 2, &#39;B&#39;
b.ResetTimer()
for i := 0; i &lt; b.N; i++ {
replaceAtIndex1(str, replacement, index)
}
}
func BenchmarkBig2(b *testing.B) {
n := 10000
str, index, replacement := generateString(n), n / 2, &#39;B&#39;
b.ResetTimer()
for i := 0; i &lt; b.N; i++ {
replaceAtIndex2(str, replacement, index)
}
}
func main(){}

shows the following results (thanks Thomasz for spotting a copypasting error):


BenchmarkSmall1-4 	10000000	       228 ns/op
BenchmarkSmall2-4 	10000000	       126 ns/op
BenchmarkMedium1-4	  500000	      2091 ns/op
BenchmarkMedium2-4	10000000	       190 ns/op
BenchmarkBig1-4   	   10000	    209232 ns/op
BenchmarkBig2-4   	  500000	      3629 ns/op

答案3

得分: 19

你可以使用 + 运算符来连接字符串:

return input[:index] + string(replacement) + input[index+1:]

请注意,index 不是一个“字母”的索引,而是一个字节的索引。

英文:

You can concatenate strings with the + operator :

return input[:index] + string(replacement) + input[index+1:]

Be careful that index isn't the index of a "letter" but of the byte.

答案4

得分: 7

只是为了好玩:

package main
import (
"fmt"
"reflect"
"syscall"
"unsafe"
)
// 我们应该这样做,因为默认情况下,Go中的字符串是只读的。
func mprotect(ptr uintptr, w bool) {
// 需要避免“EINVAL addr is not a valid pointer,
// or not a multiple of PAGESIZE.”
start := ptr & ^(uintptr(syscall.Getpagesize() - 1))
prot := syscall.PROT_READ
if w {
prot |= syscall.PROT_WRITE
}
_, _, err := syscall.Syscall(
syscall.SYS_MPROTECT,
start, uintptr(syscall.Getpagesize()),
uintptr(prot),
)
if err != 0 {
panic(err.Error())
}
}
// 这个函数非常非常非常不安全。
// 任何地方都不要使用它!
func replaceAtIndex(s string, b byte, i int) {
h := *(*reflect.StringHeader)(unsafe.Pointer(&s))
mprotect(h.Data, true)
defer mprotect(h.Data, false)
*(*byte)(unsafe.Pointer(h.Data + uintptr(i))) = b
}
func main() {
h := "Hello, playground"
replaceAtIndex(h, 'x', 0)
fmt.Println(h)
}

永远不要尝试在代码中的任何地方使用它。
它比任何标准解决方案或上面的示例都要慢得多,而且更加不安全。=)

(在playground中无法工作,因为syscall在那里没有定义)。

英文:

Just for fun:

package main                                                                                                                                                                                                
import (                                                                                                                                                                                                    
&quot;fmt&quot;                                                                                                                                                                                                   
&quot;reflect&quot;                                                                                                                                                                                               
&quot;syscall&quot;                                                                                                                                                                                               
&quot;unsafe&quot;                                                                                                                                                                                                
)                                                                                                                                                                                                           
// We should do this because by default strings in Go are read-only.                                                                                                                                                                                                                                                                                                                                                                                                                  
func mprotect(ptr uintptr, w bool) {                                                                                                                                                                        
// Need to avoid &quot;EINVAL addr is not a valid pointer,
// or not a multiple of PAGESIZE.&quot;                                                                                                                   
start := ptr &amp; ^(uintptr(syscall.Getpagesize() - 1))                                                                                                                                                    
prot := syscall.PROT_READ                                                                                                                                                                               
if w {                                                                                                                                                                                                  
prot |= syscall.PROT_WRITE                                                                                                                                                                          
}                                                                                                                                                                                                       
_, _, err := syscall.Syscall(                                                                                                                                                                           
syscall.SYS_MPROTECT,                                                                                                                                                                               
start, uintptr(syscall.Getpagesize()),                                                                                                                                                              
uintptr(prot),                                                                                                                                                                                      
)                                                                                                                                                                                                       
if err != 0 {                                                                                                                                                                                           
panic(err.Error())                                                                                                                                                                                  
}                                                                                                                                                                                                       
}                                                                                                                                                                                                           
// This function is very, very very very unsafe.                                                                                                                                                            
// Nowhere and never use it!                                                                                                                                                                                
func replaceAtIndex(s string, b byte, i int) {                                                                                                                                                              
h := *(*reflect.StringHeader)(unsafe.Pointer(&amp;s))                                                                                                                                                       
mprotect(h.Data, true)                                                                                                                                                                                  
defer mprotect(h.Data, false)                                                                                                                                                                           
*(*byte)(unsafe.Pointer(h.Data + uintptr(i))) = b                                                                                                                                                       
}                                                                                                                                                                                                           
func main() {                                                                                                                                                                                               
h := &quot;Hello, playground&quot;                                                                                                                                                                                
replaceAtIndex(h, &#39;x&#39;, 0)                                                                                                                                                                               
fmt.Println(h)                                                                                                                                                                                          
}

Never try to use it somewhere in your code.
It's slower than any standard solutions or examples above and much more unsafe. =)

(It is not working in playground, because syscall is not defined there).

答案5

得分: 4

我采用了Salvador的基准测试,并在其中添加了strings.Join()函数。他的答案仍然是正确的 - str[:index] + string(replacement) + str[index+1:]是处理大字符串时最快的选项,假设你想保留原始字符串。对于小字符串来说,strings.Join()的性能非常接近,并且对于大字符串来说非常非常接近。我还使用unsafereflect编写了另外两个实现,只是为了好玩。

  • 其中一个创建了一个副本,因此不会修改原始字符串,并且具有非常有趣的性能结果 - 对于小字符串来说更快,对于中等字符串来说更快,但对于大字符串来说要慢得多。
  • 另一个只是对可变字符串进行操作,毫不意外地,在所有情况下都要快得多,并且运行时间恒定,但原始字符串会被修改。

我还必须修改generateString()函数,以便在合理的时间范围内生成最大的字符串 How to replace a letter at a specific index in a string in Go?

以下是代码和结果:

package main
import (
	"reflect"
	"strings"
	"testing"
	"unsafe"
)

func replaceAtIndex1(str string, replacement rune, index int) string {
	out := []rune(str)
	out[index] = replacement
	return string(out)
}

func replaceAtIndex2(str string, replacement rune, index int) string {
	return str[:index] + string(replacement) + str[index+1:]
}

func replaceAtIndex3(str string, replacement rune, index int) string {
	return strings.Join([]string{str[:index], str[index + 1:]}, string(replacement))
}

func strToBytes(str string) []byte {
	string_header := (*reflect.StringHeader)(unsafe.Pointer(&str))
	bytes_header := &reflect.SliceHeader{
		Data : string_header.Data,
		Len : string_header.Len,
		Cap : string_header.Len,
	}
	return *(*[]byte)(unsafe.Pointer(bytes_header))
}

func strToBytesCopy(str string) []byte {
	bytes_unsafe := strToBytes(str)
	bytes := make([]byte, len(bytes_unsafe))
	copy(bytes, bytes_unsafe)
	return bytes
}

func bytesToStr(bytes []byte) string {
	bytes_header := (*reflect.SliceHeader)(unsafe.Pointer(&bytes))
	string_header := &reflect.StringHeader{
		Data : bytes_header.Data,
		Len : bytes_header.Len,
	}
	return *(*string)(unsafe.Pointer(string_header))
}

func replaceAtIndex4(str string, replacement rune, index int) string {
	bytes := strToBytesCopy(str)
	bytes[index] = byte(replacement)
	return bytesToStr(bytes)
}

func replaceAtIndex5(str string, replacement rune, index int) string {
	bytes := strToBytes(str)
	bytes[index] = byte(replacement)
	return bytesToStr(bytes)
}

func generateString(n int) string{
	var b strings.Builder
	b.Grow(n)
	for i := 0; i < n; i++ {
		b.WriteRune('a')
	}
	return b.String()
}

func BenchmarkSmall1(b *testing.B) {
	n := 10
	str, index, replacement := generateString(n), n / 2, 'B'

	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		replaceAtIndex1(str, replacement, index)
	}
}

func BenchmarkSmall2(b *testing.B) {
	n := 10
	str, index, replacement := generateString(n), n / 2, 'B'

	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		replaceAtIndex2(str, replacement, index)
	}
}

func BenchmarkSmall3(b *testing.B) {
	n := 10
	str, index, replacement := generateString(n), n / 2, 'B'

	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		replaceAtIndex3(str, replacement, index)
	}
}

func BenchmarkSmall4(b *testing.B) {
	n := 10
	str, index, replacement := generateString(n), n / 2, 'B'

	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		replaceAtIndex4(str, replacement, index)
	}
}

func BenchmarkSmall5(b *testing.B) {
	n := 10
	str, index, replacement := generateString(n), n / 2, 'B'

	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		replaceAtIndex5(str, replacement, index)
	}
}

func BenchmarkMedium1(b *testing.B) {
	n := 100
	str, index, replacement := generateString(n), n / 2, 'B'

	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		replaceAtIndex1(str, replacement, index)
	}
}

func BenchmarkMedium2(b *testing.B) {
	n := 100
	str, index, replacement := generateString(n), n / 2, 'B'

	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		replaceAtIndex2(str, replacement, index)
	}
}

func BenchmarkMedium3(b *testing.B) {
	n := 100
	str, index, replacement := generateString(n), n / 2, 'B'

	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		replaceAtIndex3(str, replacement, index)
	}
}

func BenchmarkMedium4(b *testing.B) {
	n := 100
	str, index, replacement := generateString(n), n / 2, 'B'

	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		replaceAtIndex4(str, replacement, index)
	}
}

func BenchmarkMedium5(b *testing.B) {
	n := 100
	str, index, replacement := generateString(n), n / 2, 'B'

	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		replaceAtIndex5(str, replacement, index)
	}
}

func BenchmarkBig1(b *testing.B) {
	n := 10000
	str, index, replacement := generateString(n), n / 2, 'B'

	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		replaceAtIndex1(str, replacement, index)
	}
}

func BenchmarkBig2(b *testing.B) {
	n := 10000
	str, index, replacement := generateString(n), n / 2, 'B'

	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		replaceAtIndex2(str, replacement, index)
	}
}

func BenchmarkBig3(b *testing.B) {
	n := 10000
	str, index, replacement := generateString(n), n / 2, 'B'

	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		replaceAtIndex3(str, replacement, index)
	}
}

func BenchmarkBig4(b *testing.B) {
	n := 10000
	str, index, replacement := generateString(n), n / 2, 'B'

	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		replaceAtIndex4(str, replacement, index)
	}
}

func BenchmarkBig5(b *testing.B) {
	n := 10000
	str, index, replacement := generateString(n), n / 2, 'B'

	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		replaceAtIndex5(str, replacement, index)
	}
}

func BenchmarkHuge2(b *testing.B) {
	n := 100000
	str, index, replacement := generateString(n), n / 2, 'B'

	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		replaceAtIndex2(str, replacement, index)
	}
}

func BenchmarkHuge3(b *testing.B) {
	n := 100000
	str, index, replacement := generateString(n), n / 2, 'B'

	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		replaceAtIndex3(str, replacement, index)
	}
}

func BenchmarkHuge4(b *testing.B) {
	n := 100000
	str, index, replacement := generateString(n), n / 2, 'B'

	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		replaceAtIndex4(str, replacement, index)
	}
}

func BenchmarkHuge5(b *testing.B) {
	n := 100000
	str, index, replacement := generateString(n), n / 2, 'B'

	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		replaceAtIndex5(str, replacement, index)
	}
}

func BenchmarkGargantuan2(b *testing.B) {
	n := 10000000
	str, index, replacement := generateString(n), n / 2, 'B'

	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		replaceAtIndex2(str, replacement, index)
	}
}

func BenchmarkGargantuan3(b *testing.B) {
	n := 10000000
	str, index, replacement := generateString(n), n / 2, 'B'

	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		replaceAtIndex3(str, replacement, index)
	}
}

func BenchmarkGargantuan4(b *testing.B) {
	n := 10000000
	str, index, replacement := generateString(n), n / 2, 'B'

	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		replaceAtIndex4(str, replacement, index)
	}
}

func BenchmarkGargantuan5(b *testing.B) {
	n := 10000000
	str, index, replacement := generateString(n), n / 2, 'B'

	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		replaceAtIndex5(str, replacement, index)
	}
}

func main(){}

结果如下:

BenchmarkSmall1-8        	20000000	        99.9 ns/op
BenchmarkSmall2-8        	50000000	        29.5 ns/op
BenchmarkSmall3-8        	20000000	        58.1 ns/op
BenchmarkSmall4-8        	50000000	        32.0 ns/op
BenchmarkSmall5-8        	1000000000	         2.93 ns/op
BenchmarkMedium1-8       	 1000000	      1034 ns/op
BenchmarkMedium2-8       	20000000	        68.4 ns/op
BenchmarkMedium3-8       	20000000	        78.8 ns/op
BenchmarkMedium4-8       	30000000	        49.3 ns/op
BenchmarkMedium5-8       	1000000000	         3.02 ns/op
BenchmarkBig1-8          	   20000	     89557 ns/op
BenchmarkBig2-8          	 1000000	      1204 ns/op
BenchmarkBig3-8          	 1000000	      1257 ns/op
BenchmarkBig4-8          	 1000000	      1200 ns/op
BenchmarkBig5-8          	1000000000	         2.93 ns/op
BenchmarkHuge2-8         	  200000	     10260 ns/op
BenchmarkHuge3-8         	  200000	      9908 ns/op
BenchmarkHuge4-8         	  100000	     13628 ns/op
BenchmarkHuge5-8         	1000000000	         2.99 ns/op
BenchmarkGargantuan2-8   	    2000	    822881 ns/op
BenchmarkGargantuan3-8   	    2000	    807522 ns/op
BenchmarkGargantuan4-8   	    1000	   2148387 ns/op
BenchmarkGargantuan5-8   	1000000000	         2.96 ns/op
英文:

I took Salvador's benchmark and added strings.Join() to it. His answer remains correct - str[:index] + string(replacement) + str[index+1:] is the fastest option for large strings assuming you want your original string preserved. strings.Join() is pretty close for small strings and very very close for large strings. I also added tests with even larger strings to see if strings.Join() becomes faster at any point - it doesn't seem to.

I also, just for funsies, hacked together two other implementations with unsafe and reflect

  • One makes a copy, so it doesn't modify the original string, and has very interesting performance results - faster for small strings, much faster for medium strings, much much slower for large strings
  • The other just does a mutable string and is, unsurprisingly, drastically faster for all purposes and runs in constant time, with the caveat that your original string is modified.

I also had to modify generateString() so it would the largest strings would generate in a reasonable timeframe How to replace a letter at a specific index in a string in Go?

Anyway, the code:

<!-- language: go -->

package main
import (
&quot;reflect&quot;
&quot;strings&quot;
&quot;testing&quot;
&quot;unsafe&quot;
)
func replaceAtIndex1(str string, replacement rune, index int) string {
out := []rune(str)
out[index] = replacement
return string(out)
}
func replaceAtIndex2(str string, replacement rune, index int) string {
return str[:index] + string(replacement) + str[index+1:]
}
func replaceAtIndex3(str string, replacement rune, index int) string {
return strings.Join([]string{str[:index], str[index + 1:]}, string(replacement))
}
func strToBytes(str string) []byte {
string_header := (*reflect.StringHeader)(unsafe.Pointer(&amp;str))
bytes_header := &amp;reflect.SliceHeader{
Data : string_header.Data,
Len : string_header.Len,
Cap : string_header.Len,
}
return *(*[]byte)(unsafe.Pointer(bytes_header))
}
func strToBytesCopy(str string) []byte {
bytes_unsafe := strToBytes(str)
bytes := make([]byte, len(bytes_unsafe))
copy(bytes, bytes_unsafe)
return bytes
}
func bytesToStr(bytes []byte) string {
bytes_header := (*reflect.SliceHeader)(unsafe.Pointer(&amp;bytes))
string_header := &amp;reflect.StringHeader{
Data : bytes_header.Data,
Len : bytes_header.Len,
}
return *(*string)(unsafe.Pointer(string_header))
}
func replaceAtIndex4(str string, replacement rune, index int) string {
bytes := strToBytesCopy(str)
bytes[index] = byte(replacement)
return bytesToStr(bytes)
}
func replaceAtIndex5(str string, replacement rune, index int) string {
bytes := strToBytes(str)
bytes[index] = byte(replacement)
return bytesToStr(bytes)
}
func generateString(n int) string{
var b strings.Builder
b.Grow(n)
for i := 0; i &lt; n; i++ {
b.WriteRune(&#39;a&#39;)
}
return b.String()
}
func BenchmarkSmall1(b *testing.B) {
n := 10
str, index, replacement := generateString(n), n / 2, &#39;B&#39;
b.ResetTimer()
for i := 0; i &lt; b.N; i++ {
replaceAtIndex1(str, replacement, index)
}
}
func BenchmarkSmall2(b *testing.B) {
n := 10
str, index, replacement := generateString(n), n / 2, &#39;B&#39;
b.ResetTimer()
for i := 0; i &lt; b.N; i++ {
replaceAtIndex2(str, replacement, index)
}
}
func BenchmarkSmall3(b *testing.B) {
n := 10
str, index, replacement := generateString(n), n / 2, &#39;B&#39;
b.ResetTimer()
for i := 0; i &lt; b.N; i++ {
replaceAtIndex3(str, replacement, index)
}
}
func BenchmarkSmall4(b *testing.B) {
n := 10
str, index, replacement := generateString(n), n / 2, &#39;B&#39;
b.ResetTimer()
for i := 0; i &lt; b.N; i++ {
replaceAtIndex4(str, replacement, index)
}
}
func BenchmarkSmall5(b *testing.B) {
n := 10
str, index, replacement := generateString(n), n / 2, &#39;B&#39;
b.ResetTimer()
for i := 0; i &lt; b.N; i++ {
replaceAtIndex5(str, replacement, index)
}
}
func BenchmarkMedium1(b *testing.B) {
n := 100
str, index, replacement := generateString(n), n / 2, &#39;B&#39;
b.ResetTimer()
for i := 0; i &lt; b.N; i++ {
replaceAtIndex1(str, replacement, index)
}
}
func BenchmarkMedium2(b *testing.B) {
n := 100
str, index, replacement := generateString(n), n / 2, &#39;B&#39;
b.ResetTimer()
for i := 0; i &lt; b.N; i++ {
replaceAtIndex2(str, replacement, index)
}
}
func BenchmarkMedium3(b *testing.B) {
n := 100
str, index, replacement := generateString(n), n / 2, &#39;B&#39;
b.ResetTimer()
for i := 0; i &lt; b.N; i++ {
replaceAtIndex3(str, replacement, index)
}
}
func BenchmarkMedium4(b *testing.B) {
n := 100
str, index, replacement := generateString(n), n / 2, &#39;B&#39;
b.ResetTimer()
for i := 0; i &lt; b.N; i++ {
replaceAtIndex4(str, replacement, index)
}
}
func BenchmarkMedium5(b *testing.B) {
n := 100
str, index, replacement := generateString(n), n / 2, &#39;B&#39;
b.ResetTimer()
for i := 0; i &lt; b.N; i++ {
replaceAtIndex5(str, replacement, index)
}
}
func BenchmarkBig1(b *testing.B) {
n := 10000
str, index, replacement := generateString(n), n / 2, &#39;B&#39;
b.ResetTimer()
for i := 0; i &lt; b.N; i++ {
replaceAtIndex1(str, replacement, index)
}
}
func BenchmarkBig2(b *testing.B) {
n := 10000
str, index, replacement := generateString(n), n / 2, &#39;B&#39;
b.ResetTimer()
for i := 0; i &lt; b.N; i++ {
replaceAtIndex2(str, replacement, index)
}
}
func BenchmarkBig3(b *testing.B) {
n := 10000
str, index, replacement := generateString(n), n / 2, &#39;B&#39;
b.ResetTimer()
for i := 0; i &lt; b.N; i++ {
replaceAtIndex3(str, replacement, index)
}
}
func BenchmarkBig4(b *testing.B) {
n := 10000
str, index, replacement := generateString(n), n / 2, &#39;B&#39;
b.ResetTimer()
for i := 0; i &lt; b.N; i++ {
replaceAtIndex4(str, replacement, index)
}
}
func BenchmarkBig5(b *testing.B) {
n := 10000
str, index, replacement := generateString(n), n / 2, &#39;B&#39;
b.ResetTimer()
for i := 0; i &lt; b.N; i++ {
replaceAtIndex5(str, replacement, index)
}
}
func BenchmarkHuge2(b *testing.B) {
n := 100000
str, index, replacement := generateString(n), n / 2, &#39;B&#39;
b.ResetTimer()
for i := 0; i &lt; b.N; i++ {
replaceAtIndex2(str, replacement, index)
}
}
func BenchmarkHuge3(b *testing.B) {
n := 100000
str, index, replacement := generateString(n), n / 2, &#39;B&#39;
b.ResetTimer()
for i := 0; i &lt; b.N; i++ {
replaceAtIndex3(str, replacement, index)
}
}
func BenchmarkHuge4(b *testing.B) {
n := 100000
str, index, replacement := generateString(n), n / 2, &#39;B&#39;
b.ResetTimer()
for i := 0; i &lt; b.N; i++ {
replaceAtIndex4(str, replacement, index)
}
}
func BenchmarkHuge5(b *testing.B) {
n := 100000
str, index, replacement := generateString(n), n / 2, &#39;B&#39;
b.ResetTimer()
for i := 0; i &lt; b.N; i++ {
replaceAtIndex5(str, replacement, index)
}
}
func BenchmarkGargantuan2(b *testing.B) {
n := 10000000
str, index, replacement := generateString(n), n / 2, &#39;B&#39;
b.ResetTimer()
for i := 0; i &lt; b.N; i++ {
replaceAtIndex2(str, replacement, index)
}
}
func BenchmarkGargantuan3(b *testing.B) {
n := 10000000
str, index, replacement := generateString(n), n / 2, &#39;B&#39;
b.ResetTimer()
for i := 0; i &lt; b.N; i++ {
replaceAtIndex3(str, replacement, index)
}
}
func BenchmarkGargantuan4(b *testing.B) {
n := 10000000
str, index, replacement := generateString(n), n / 2, &#39;B&#39;
b.ResetTimer()
for i := 0; i &lt; b.N; i++ {
replaceAtIndex4(str, replacement, index)
}
}
func BenchmarkGargantuan5(b *testing.B) {
n := 10000000
str, index, replacement := generateString(n), n / 2, &#39;B&#39;
b.ResetTimer()
for i := 0; i &lt; b.N; i++ {
replaceAtIndex5(str, replacement, index)
}
}
func main(){}

And the results:

BenchmarkSmall1-8        	20000000	        99.9 ns/op
BenchmarkSmall2-8        	50000000	        29.5 ns/op
BenchmarkSmall3-8        	20000000	        58.1 ns/op
BenchmarkSmall4-8        	50000000	        32.0 ns/op
BenchmarkSmall5-8        	1000000000	         2.93 ns/op
BenchmarkMedium1-8       	 1000000	      1034 ns/op
BenchmarkMedium2-8       	20000000	        68.4 ns/op
BenchmarkMedium3-8       	20000000	        78.8 ns/op
BenchmarkMedium4-8       	30000000	        49.3 ns/op
BenchmarkMedium5-8       	1000000000	         3.02 ns/op
BenchmarkBig1-8          	   20000	     89557 ns/op
BenchmarkBig2-8          	 1000000	      1204 ns/op
BenchmarkBig3-8          	 1000000	      1257 ns/op
BenchmarkBig4-8          	 1000000	      1200 ns/op
BenchmarkBig5-8          	1000000000	         2.93 ns/op
BenchmarkHuge2-8         	  200000	     10260 ns/op
BenchmarkHuge3-8         	  200000	      9908 ns/op
BenchmarkHuge4-8         	  100000	     13628 ns/op
BenchmarkHuge5-8         	1000000000	         2.99 ns/op
BenchmarkGargantuan2-8   	    2000	    822881 ns/op
BenchmarkGargantuan3-8   	    2000	    807522 ns/op
BenchmarkGargantuan4-8   	    1000	   2148387 ns/op
BenchmarkGargantuan5-8   	1000000000	         2.96 ns/op

huangapple
  • 本文由 发表于 2014年7月23日 01:11:00
  • 转载请务必保留本文链接:https://go.coder-hub.com/24893624.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定