在用Go做一个SQL生成的工具,对他的字符串拼接的性能表示好奇,在google搜了半天,好像认真的老外都没有这方面的结果,所以自己动手弄一个吧!
|
---|
哦,是的,字符串+是最快的,当然这里只是一个简单测试的结果,具体情况还是选择最符合使用场景的方法吧。
如果有新结果,会更新到这边:http://git.oschina.net/janpoem/go-benchmarks
package main import ( "git.oschina.net/janpoem/go-agi" ) import ( "fmt" "math/rand" "strconv" "bytes" "strings" ) func randStr() (string) { return strconv.FormatInt(rand.Int63(), 36) } var sp_str1 = randStr() var sp_str2 = randStr() var sp_str3 = randStr() var sp_str4 = randStr() var sp_str5 = randStr() var sp_str6 = randStr() func test_2_args() { max := 1000000 dur1 := agi.TimesTest(max, func() { fmt.Sprintf("SELECT %s FROM %s", sp_str1, sp_str2) }) dur2 := agi.TimesTest(max, func() { bf := bytes.NewBufferString("SELECT") bf.WriteString(" ") bf.WriteString(sp_str1) bf.WriteString(" ") bf.WriteString("FROM") bf.WriteString(sp_str2) }) dur3 := agi.TimesTest(max, func() { bf := "SELECT " + sp_str1 + " FROM " + sp_str2 if len(bf) > 0 { } }) dur4 := agi.TimesTest(max, func() { bf := strings.Join([]string { "SELECT", sp_str1, "FROM", sp_str2 }, "") if len(bf) > 0 { } }) fmt.Println(dur1.Seconds()) fmt.Println(dur2.Seconds()) fmt.Println(dur3.Seconds()) fmt.Println(dur4.Seconds()) } func test_4_args() { max := 1000000 dur1 := agi.TimesTest(max, func() { fmt.Sprintf("SELECT %s FROM %s WHERE %s ORDER BY %s", sp_str1, sp_str2, sp_str3, sp_str4) }) dur2 := agi.TimesTest(max, func() { bf := bytes.NewBufferString("SELECT ") bf.WriteString(sp_str1) bf.WriteString(" ") bf.WriteString("FROM ") bf.WriteString(sp_str2) bf.WriteString(" ") bf.WriteString("WHERE ") bf.WriteString(sp_str3) bf.WriteString(" ") bf.WriteString("ORDER BY ") bf.WriteString(sp_str4) }) dur3 := agi.TimesTest(max, func() { bf := "SELECT " + sp_str1 + " FROM " + sp_str2 + " WHERE " + sp_str3 + " ORDER BY " + sp_str4 if len(bf) > 0 { } }) dur4 := agi.TimesTest(max, func() { bf := strings.Join([]string { "SELECT", sp_str1, "FROM", sp_str2, "WHERE", sp_str3, "ORDER BY", sp_str4 }, "") if len(bf) > 0 { } }) fmt.Println(dur1.Seconds()) fmt.Println(dur2.Seconds()) fmt.Println(dur3.Seconds()) fmt.Println(dur4.Seconds()) } func test_6_args() { max := 1000000 dur1 := agi.TimesTest(max, func() { fmt.Sprintf("SELECT %s FROM %s WHERE %s ORDER BY %s GROUP BY %s LIMIT %s", sp_str1, sp_str2, sp_str3, sp_str4, sp_str5, sp_str6) }) dur2 := agi.TimesTest(max, func() { bf := bytes.NewBufferString("SELECT ") bf.WriteString(sp_str1) bf.WriteString(" ") bf.WriteString("FROM ") bf.WriteString(sp_str2) bf.WriteString(" ") bf.WriteString("WHERE ") bf.WriteString(sp_str3) bf.WriteString(" ") bf.WriteString("ORDER BY ") bf.WriteString(sp_str4) bf.WriteString(" ") bf.WriteString("GROUP BY ") bf.WriteString(sp_str5) bf.WriteString(" ") bf.WriteString("LIMIT ") bf.WriteString(sp_str6) }) dur3 := agi.TimesTest(max, func() { bf := "SELECT " + sp_str1 + " FROM " + sp_str2 + " WHERE " + sp_str3 + " ORDER BY " + sp_str4 + " GROUP BY " + sp_str5 + " LIMIT " + sp_str6 if len(bf) > 0 { } }) dur4 := agi.TimesTest(max, func() { bf := strings.Join([]string { "SELECT", sp_str1, "FROM", sp_str2, "WHERE", sp_str3, "ORDER BY", sp_str4, "GROUP BY", sp_str5, "LIMIT", sp_str6, }, "") if len(bf) > 0 { } }) fmt.Println(dur1.Seconds()) fmt.Println(dur2.Seconds()) fmt.Println(dur3.Seconds()) fmt.Println(dur4.Seconds()) } func main() { // test_2_args() // test_4_args() // test_6_args() }
具体代码在这里:http://git.oschina.net/janpoem/go-benchmarks/blob/master/str_concat.go
TimesTest,调用的是这个:benchmark.go,他的功能就是根据你传入的次数,执行指定的匿名函数多少次。起初对执行匿名函数的效能有些担心,不过比较了一下裸代码和匿名函数的执行时间,相差的并不多,就忽略吧。
这次测试只是对执行时间的一个测试,不包含CPU和内存情况监控。
呃,额外的说, @红薯 博客的markdown编辑器是不是太奇葩了,table、代码,什么格式都不支持,太难用了。