mirror of
https://gitee.com/johng/gf
synced 2026-06-07 02:12:11 +08:00
改进grand随机数生成设计,底层使用crypto/rand+缓冲区实现高速的随机数生成;gtime模块增加FuncCost函数执行耗时计算
This commit is contained in:
@ -26,7 +26,7 @@ type Session struct {
|
||||
server *Server // 所属Server
|
||||
}
|
||||
|
||||
// 生成一个唯一的sessionid字符串
|
||||
// 生成一个唯一的sessionid字符串,长度16
|
||||
func makeSessionId() string {
|
||||
return strings.ToUpper(strconv.FormatInt(gtime.Nanosecond(), 32) + grand.RandStr(3))
|
||||
}
|
||||
|
||||
@ -306,4 +306,11 @@ func ParseTimeFromContent(content string, format...string) *Time {
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// 计算函数f执行的时间,单位纳秒
|
||||
func FuncCost(f func()) int64 {
|
||||
t := Nanosecond()
|
||||
f()
|
||||
return Nanosecond() - t
|
||||
}
|
||||
@ -15,7 +15,7 @@ import (
|
||||
"strings"
|
||||
)
|
||||
|
||||
// 将变量i转换为字符串指定的类型t,非必须参数extraParams泳衣额外的参数传递
|
||||
// 将变量i转换为字符串指定的类型t,非必须参数extraParams用以额外的参数传递
|
||||
func Convert(i interface{}, t string, extraParams...interface{}) interface{} {
|
||||
switch t {
|
||||
case "int": return Int(i)
|
||||
|
||||
@ -7,18 +7,9 @@
|
||||
// 随机数管理
|
||||
package grand
|
||||
|
||||
import (
|
||||
"time"
|
||||
)
|
||||
|
||||
var letters = []rune("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789")
|
||||
var digits = []rune("0123456789")
|
||||
|
||||
// 自定义的 rand.Intn
|
||||
func intn (max int) int {
|
||||
return int(time.Now().UnixNano())%max
|
||||
}
|
||||
|
||||
// 获得一个 min, max 之间的随机数(min <= x <= max)
|
||||
func Rand (min, max int) int {
|
||||
if min >= max {
|
||||
|
||||
45
g/util/grand/grand_intn.go
Normal file
45
g/util/grand/grand_intn.go
Normal file
@ -0,0 +1,45 @@
|
||||
// Copyright 2018 gf Author(https://gitee.com/johng/gf). All Rights Reserved.
|
||||
//
|
||||
// This Source Code Form is subject to the terms of the MIT License.
|
||||
// If a copy of the MIT was not distributed with this file,
|
||||
// You can obtain one at https://gitee.com/johng/gf.
|
||||
|
||||
package grand
|
||||
|
||||
import (
|
||||
"crypto/rand"
|
||||
"encoding/binary"
|
||||
)
|
||||
|
||||
const (
|
||||
gBUFFER_SIZE = 10000 // 缓冲区uint64数量大小
|
||||
)
|
||||
|
||||
var (
|
||||
bufferChan = make(chan uint64, gBUFFER_SIZE)
|
||||
)
|
||||
|
||||
// 使用缓冲区实现快速的随机数生成
|
||||
func init() {
|
||||
buffer := make([]byte, 1024)
|
||||
go func() {
|
||||
for {
|
||||
if n, err := rand.Read(buffer); err != nil {
|
||||
panic(err)
|
||||
} else {
|
||||
for i := 0; i < n - 8; i += 8 {
|
||||
bufferChan <- binary.LittleEndian.Uint64(buffer[i : i + 8])
|
||||
}
|
||||
}
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
// 自定义的 rand.Intn ,绝对随机
|
||||
func intn (max int) int {
|
||||
n := int(<- bufferChan)%max
|
||||
if n < 0 {
|
||||
return -n
|
||||
}
|
||||
return n
|
||||
}
|
||||
@ -15,6 +15,6 @@ import (
|
||||
|
||||
func Benchmark_Rand(b *testing.B) {
|
||||
for i := 0; i < b.N; i++ {
|
||||
grand.Rand(0, 200)
|
||||
grand.Rand(0, 999999999)
|
||||
}
|
||||
}
|
||||
|
||||
@ -3,13 +3,11 @@ package main
|
||||
import (
|
||||
"fmt"
|
||||
"gitee.com/johng/gf/g/os/gtime"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
func main() {
|
||||
s := `
|
||||
[INFO] 2018-11-04 12:48:01 2018-11-04 12:48:01 ["handle eventMedlinker\\Med3Svr\\App\\Events\\Task\\InviteUserVerifyEvent::__set_state(array(\n 'deviceNum' => '25a715ff8d4835197299d7dab067841e',\n 'userIdList' => \n array (\n 0 => '62506063',\n ),\n 'dataId' => '',\n 'eventTime' => NULL,\n))"] [med3-svr-6c8c9b9f4f-fl6g9]
|
||||
|
||||
`
|
||||
t := gtime.ParseTimeFromContent(s)
|
||||
fmt.Println(t.String())
|
||||
fmt.Println(strconv.FormatInt(gtime.Nanosecond(), 32))
|
||||
fmt.Println(gtime.Second())
|
||||
fmt.Println(gtime.Nanosecond())
|
||||
}
|
||||
12
geg/util/grand/grand.go
Normal file
12
geg/util/grand/grand.go
Normal file
@ -0,0 +1,12 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"gitee.com/johng/gf/g/util/grand"
|
||||
)
|
||||
|
||||
func main() {
|
||||
for i := 0; i < 10; i++ {
|
||||
fmt.Println(grand.Rand(0, 99999))
|
||||
}
|
||||
}
|
||||
83
geg/util/grand/rand.go
Normal file
83
geg/util/grand/rand.go
Normal file
@ -0,0 +1,83 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
crand "crypto/rand"
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
"gitee.com/johng/gf/g/os/gtime"
|
||||
mrand "math/rand"
|
||||
"os"
|
||||
"time"
|
||||
)
|
||||
|
||||
// int 随机
|
||||
func a1() {
|
||||
s1 := mrand.NewSource(time.Now().UnixNano())
|
||||
r1 := mrand.New(s1)
|
||||
for i := 0; i < 10; i++ {
|
||||
fmt.Printf("%d ", r1.Intn(100))
|
||||
}
|
||||
fmt.Printf("\n")
|
||||
}
|
||||
|
||||
// 0/1 true/false 随机
|
||||
func a2() {
|
||||
// Go编程这本书上例子.
|
||||
ch := make(chan int, 1)
|
||||
for i := 0; i < 10; i++ {
|
||||
select {
|
||||
case ch <- 0:
|
||||
case ch <- 1:
|
||||
}
|
||||
r := <-ch
|
||||
fmt.Printf("%d ", r)
|
||||
}
|
||||
fmt.Printf("\n")
|
||||
}
|
||||
|
||||
//真随机 -- 用标准库封装好的
|
||||
func a3() {
|
||||
b := make([]byte, 16)
|
||||
// On Unix-like systems, Reader reads from /dev/urandom.
|
||||
// On Windows systems, Reader uses the CryptGenRandom API.
|
||||
_, err := crand.Read(b) //返回长度为0 - 32 的值
|
||||
if err != nil {
|
||||
fmt.Println("[a3] ", err)
|
||||
return
|
||||
}
|
||||
fmt.Println("[a3] b:", b)
|
||||
}
|
||||
|
||||
//真随机 -- 我们直接调真随机文件生成了事。 但注意,它是阻塞式的。
|
||||
func a4() {
|
||||
f, err := os.Open("/dev/random")
|
||||
if err != nil {
|
||||
fmt.Println("[a4] ", err)
|
||||
return
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
b1 := make([]byte, 16)
|
||||
_, err = f.Read(b1)
|
||||
if err != nil {
|
||||
fmt.Println("[a4] ", err)
|
||||
return
|
||||
}
|
||||
fmt.Println("[a4] Read /dev/random:", b1)
|
||||
}
|
||||
|
||||
// a3 的另一种实现方式
|
||||
func a5() {
|
||||
var ret int32
|
||||
binary.Read(crand.Reader, binary.LittleEndian, &ret)
|
||||
fmt.Println("[a5] ret:", ret)
|
||||
}
|
||||
|
||||
func main() {
|
||||
fmt.Println("a1:", gtime.FuncCost(a1))
|
||||
fmt.Println("a2:", gtime.FuncCost(a2))
|
||||
fmt.Println("a3:", gtime.FuncCost(a3))
|
||||
fmt.Println("a4:", gtime.FuncCost(a4))
|
||||
fmt.Println("a5:", gtime.FuncCost(a5))
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user