diff --git a/.example/util/grand/grand.go b/.example/util/grand/grand.go index 579b9053f..2823027a8 100644 --- a/.example/util/grand/grand.go +++ b/.example/util/grand/grand.go @@ -10,4 +10,7 @@ func main() { for i := 0; i < 100; i++ { fmt.Println(grand.S(16)) } + for i := 0; i < 100; i++ { + fmt.Println(grand.N(0, 99999999)) + } } diff --git a/.example/util/guid/guid.go b/.example/util/guid/guid.go index 439cf9869..057d10454 100644 --- a/.example/util/guid/guid.go +++ b/.example/util/guid/guid.go @@ -6,5 +6,8 @@ import ( ) func main() { - fmt.Printf("TraceId: %s\n", guid.S()) + for i := 0; i < 100; i++ { + s := guid.S() + fmt.Println(s, len(s)) + } } diff --git a/.example/util/guid/guid_length.go b/.example/util/guid/guid_length.go index 1e5c642d6..c04c594f8 100644 --- a/.example/util/guid/guid_length.go +++ b/.example/util/guid/guid_length.go @@ -7,9 +7,14 @@ import ( ) func main() { - fmt.Println(strconv.FormatUint(4589634556, 36)) - fmt.Println(strconv.FormatUint(math.MaxUint64-2, 36)) - fmt.Println(strconv.FormatUint(math.MaxUint32-1, 36)) - fmt.Println(strconv.FormatUint(math.MaxUint32, 36)) - fmt.Println(strconv.FormatUint(2000000, 36)) + // 36*36^2+36*36+36 + var s string + fmt.Println(strconv.ParseUint("zzz", 36, 3)) + fmt.Println(1 << 1) + // MaxInt64 + s = strconv.FormatUint(math.MaxUint64, 16) + fmt.Println(s, len(s)) + // PID + s = strconv.FormatInt(1000000, 36) + fmt.Println(s, len(s)) } diff --git a/.example/util/guid/guid_unique.go b/.example/util/guid/guid_unique.go index 4009e305b..4872a1634 100644 --- a/.example/util/guid/guid_unique.go +++ b/.example/util/guid/guid_unique.go @@ -6,17 +6,17 @@ import ( ) func main() { - for i := 0; i < 10; i++ { + for i := 0; i < 100; i++ { s := guid.S([]byte("123")) fmt.Println(s, len(s)) } fmt.Println() - for i := 0; i < 10; i++ { + for i := 0; i < 100; i++ { s := guid.S([]byte("123"), []byte("456")) fmt.Println(s, len(s)) } fmt.Println() - for i := 0; i < 10; i++ { + for i := 0; i < 100; i++ { s := guid.S([]byte("123"), []byte("456"), []byte("789")) fmt.Println(s, len(s)) } diff --git a/encoding/gbinary/gbinary_bits.go b/encoding/gbinary/gbinary_bit.go similarity index 97% rename from encoding/gbinary/gbinary_bits.go rename to encoding/gbinary/gbinary_bit.go index d477346eb..04cdd32bb 100644 --- a/encoding/gbinary/gbinary_bits.go +++ b/encoding/gbinary/gbinary_bit.go @@ -6,7 +6,7 @@ package gbinary -// 实验特性 +// NOTE: THIS IS AN EXPERIMENTAL FEATURE! // 二进制位(0|1) type Bit int8 diff --git a/net/ghttp/ghttp_request.go b/net/ghttp/ghttp_request.go index 104b85294..97e629130 100644 --- a/net/ghttp/ghttp_request.go +++ b/net/ghttp/ghttp_request.go @@ -9,6 +9,7 @@ package ghttp import ( "context" "fmt" + "github.com/gogf/gf/internal/intlog" "github.com/gogf/gf/os/gres" "github.com/gogf/gf/os/gsession" "github.com/gogf/gf/os/gview" @@ -79,12 +80,11 @@ func newRequest(s *Server, r *http.Request, w http.ResponseWriter) *Request { // Custom session id creating function. err := request.Session.SetIdFunc(func(ttl time.Duration) string { var ( - agent = request.UserAgent() address = request.RemoteAddr - cookie = request.Header.Get("Cookie") + header = fmt.Sprintf("%v", request.Header) ) - //intlog.Print(agent, address, cookie) - return guid.S([]byte(agent), []byte(address), []byte(cookie)) + intlog.Print(address, header) + return guid.S([]byte(address), []byte(header)) }) if err != nil { panic(err) diff --git a/os/gtime/gtime_z_bench_test.go b/os/gtime/gtime_z_bench_test.go index a099e20e7..85408cf10 100644 --- a/os/gtime/gtime_z_bench_test.go +++ b/os/gtime/gtime_z_bench_test.go @@ -12,25 +12,25 @@ import ( "github.com/gogf/gf/os/gtime" ) -func Benchmark_Second(b *testing.B) { +func Benchmark_Timestamp(b *testing.B) { for i := 0; i < b.N; i++ { gtime.Timestamp() } } -func Benchmark_Millisecond(b *testing.B) { +func Benchmark_TimestampMilli(b *testing.B) { for i := 0; i < b.N; i++ { gtime.TimestampMilli() } } -func Benchmark_Microsecond(b *testing.B) { +func Benchmark_TimestampMicro(b *testing.B) { for i := 0; i < b.N; i++ { gtime.TimestampMicro() } } -func Benchmark_Nanosecond(b *testing.B) { +func Benchmark_TimestampNano(b *testing.B) { for i := 0; i < b.N; i++ { gtime.TimestampNano() } diff --git a/util/grand/grand_buffer.go b/util/grand/grand_buffer.go index d83801edb..2d108e4f7 100644 --- a/util/grand/grand_buffer.go +++ b/util/grand/grand_buffer.go @@ -37,23 +37,12 @@ func asyncProducingRandomBufferBytesLoop() { } else { // The random buffer from system is very expensive, // so fully reuse the random buffer by changing - // the step with a different prime number can + // the step with a different number can // improve the performance a lot. - step = 4 - for i := 0; i < n-4; i += step { - bufferChan <- buffer[i : i+4] - } - step = 5 - for i := 0; i < n-4; i += step { - bufferChan <- buffer[i : i+4] - } - step = 7 - for i := 0; i < n-4; i += step { - bufferChan <- buffer[i : i+4] - } - step = 13 - for i := 0; i < n-4; i += step { - bufferChan <- buffer[i : i+4] + for _, step = range []int{4, 5, 6, 7} { + for i := 0; i <= n-4; i += step { + bufferChan <- buffer[i : i+4] + } } } } diff --git a/util/grand/grand_z_bench_test.go b/util/grand/grand_z_bench_test.go index 08a09cd52..fc3a165ca 100644 --- a/util/grand/grand_z_bench_test.go +++ b/util/grand/grand_z_bench_test.go @@ -17,11 +17,25 @@ import ( ) var ( - buffer = make([]byte, 8) - strForStr = "我爱GoFrame" + buffer = make([]byte, 8) + randBuffer4 = make([]byte, 4) + randBuffer1024 = make([]byte, 1024) + strForStr = "我爱GoFrame" ) -func Benchmark_Rand_Intn(b *testing.B) { +func Benchmark_Rand_Buffer4(b *testing.B) { + for i := 0; i < b.N; i++ { + rand.Read(randBuffer4) + } +} + +func Benchmark_Rand_Buffer1024(b *testing.B) { + for i := 0; i < b.N; i++ { + rand.Read(randBuffer1024) + } +} + +func Benchmark_GRand_Intn(b *testing.B) { for i := 0; i < b.N; i++ { grand.N(0, 99) } diff --git a/util/guid/guid.go b/util/guid/guid.go index 4801819ee..c289d2c4e 100644 --- a/util/guid/guid.go +++ b/util/guid/guid.go @@ -25,7 +25,7 @@ import ( var ( sequence gtype.Uint32 // Sequence for unique purpose of current process. - sequenceMax = uint32(1000000) // Sequence max. + sequenceMax = uint32(46655) // Sequence max("zzz"). randomStrBase = "0123456789abcdefghijklmnopqrstuvwxyz" // Random chars string(36 bytes). macAddrStr = "0000000" // MAC addresses hash result in 7 bytes. processIdStr = "0000" // Process id in 4 bytes. @@ -42,47 +42,47 @@ func init() { } b := []byte{'0', '0', '0', '0', '0', '0', '0'} s := strconv.FormatUint(uint64(ghash.DJBHash(macAddrBytes)), 36) - copy(b[7-len(s):], s) + copy(b, s) macAddrStr = string(b) } // Process id in 4 bytes. { b := []byte{'0', '0', '0', '0'} s := strconv.FormatInt(int64(os.Getpid()), 36) - copy(b[4-len(s):], s) + copy(b, s) processIdStr = string(b) } } -// S creates and returns an unique string in 36 bytes that meets most common usages -// without strict UUID algorithm. It returns an unique string using default unique -// algorithm if no is given. +// S creates and returns a global unique string in 32 bytes that meets most common +// usages without strict UUID algorithm. It returns an unique string using default +// unique algorithm if no is given. // -// The specified can be no more than 3 count. No matter how long each of the -// size is, each of them will be hashed into 7 bytes as part of the result. If given -// count is less than 3, the leftover size of the result bytes will be token by -// random string. +// The specified can be no more than 2 count. No matter how long each of the +// size is, each of them will be hashed into 7 bytes as part of the result. +// If given count is less than 2, the leftover size of the result bytes will +// be token by random string. // // The returned string is composed with: -// 1. Default: MAC(7) + PID(4) + Sequence(4) + TimestampNano(12) + RandomString(9) -// 2. CustomData: Data...(7 - 21) + TimestampNano(12) + RandomString(3 - 17) +// 1. Default: MAC(7) + PID(4) + TimestampNano(12) + Sequence(3) + RandomString(6) +// 2. CustomData: Data(7/14) + TimestampNano(12) + Sequence(3) + RandomString(3/10) // // Note that: -// 1. The returned length is fixed to 36 bytes for performance purpose. +// 1. The returned length is fixed to 32 bytes for performance purpose. // 2. The custom parameter composed should have unique attribute in your // business situation. func S(data ...[]byte) string { var ( - b = make([]byte, 36) + b = make([]byte, 32) nanoStr = strconv.FormatInt(time.Now().UnixNano(), 36) ) if len(data) == 0 { copy(b, macAddrStr) copy(b[7:], processIdStr) - copy(b[11:], getSequence()) - copy(b[15:], nanoStr) - copy(b[27:], getRandomStr(9)) - } else if len(data) <= 3 { + copy(b[11:], nanoStr) + copy(b[23:], getSequence()) + copy(b[26:], getRandomStr(6)) + } else if len(data) <= 2 { n := 0 for i, v := range data { // Ignore empty data item bytes. @@ -92,26 +92,27 @@ func S(data ...[]byte) string { } } copy(b[n:], nanoStr) - copy(b[n+12:], getRandomStr(36-n-12)) + copy(b[n+12:], getSequence()) + copy(b[n+12+3:], getRandomStr(32-n-12-3)) } else { - panic("data count too long, no more than 3") + panic("data count too long, no more than 2") } return gconv.UnsafeBytesToStr(b) } -// getSequence increases and returns the sequence string in 4 bytes. -// The sequence is less than 1000000. -func getSequence() string { - b := []byte{'0', '0', '0', '0'} +// getSequence increases and returns the sequence string in 3 bytes. +// The sequence is less than "zzz"(46655). +func getSequence() []byte { + b := []byte{'0', '0', '0'} s := strconv.FormatUint(uint64(sequence.Add(1)%sequenceMax), 36) - copy(b[4-len(s):], s) - return gconv.UnsafeBytesToStr(b) + copy(b, s) + return b } // getRandomStr randomly picks and returns count of chars from randomStrBase. -func getRandomStr(n int) string { +func getRandomStr(n int) []byte { if n <= 0 { - return "" + return []byte{} } var ( b = make([]byte, n) @@ -120,13 +121,13 @@ func getRandomStr(n int) string { for i := range b { b[i] = randomStrBase[numberBytes[i]%36] } - return gconv.UnsafeBytesToStr(b) + return b } // getDataHashStr creates and returns hash bytes in 7 bytes with given data bytes. -func getDataHashStr(data []byte) string { +func getDataHashStr(data []byte) []byte { b := []byte{'0', '0', '0', '0', '0', '0', '0'} s := strconv.FormatUint(uint64(ghash.DJBHash(data)), 36) - copy(b[7-len(s):], s) - return gconv.UnsafeBytesToStr(b) + copy(b, s) + return b } diff --git a/util/guid/guid_z_bench_test.go b/util/guid/guid_z_bench_test.go index 5384bfdee..bac93d917 100644 --- a/util/guid/guid_z_bench_test.go +++ b/util/guid/guid_z_bench_test.go @@ -30,9 +30,3 @@ func Benchmark_S_Data_2(b *testing.B) { guid.S([]byte("123"), []byte("456")) } } - -func Benchmark_S_Data_3(b *testing.B) { - for i := 0; i < b.N; i++ { - guid.S([]byte("123"), []byte("456"), []byte("789")) - } -} diff --git a/util/guid/guid_z_unit_test.go b/util/guid/guid_z_unit_test.go index 0e8716385..1b35fdb9a 100644 --- a/util/guid/guid_z_unit_test.go +++ b/util/guid/guid_z_unit_test.go @@ -22,13 +22,13 @@ func Test_S(t *testing.T) { for i := 0; i < 1000000; i++ { s := guid.S() t.Assert(set.AddIfNotExist(s), true) - t.Assert(len(s), 36) + t.Assert(len(s), 32) } }) } func Test_S_Data(t *testing.T) { gtest.C(t, func(t *gtest.T) { - t.Assert(len(guid.S([]byte("123"))), 36) + t.Assert(len(guid.S([]byte("123"))), 32) }) }