加权随机索引比较常用,例如HTTP代理服务器需要按照不同的权重把请求转发给不同的后端服务器,又比如在web页面的同一个位置需要按照一定的比例显示不同的广告图片。

函数实现如下:

输出:

[108 189 291 412]

以Go内置的rand.Intn函数作为参照,进行性能对照测试:

package main

import (
	"math/rand"
	"testing"
	"time"
)

var weights = []float32{0.1, 0.2, 0.3, 0.4}
var n int = len(weights)

func BenchmarkWeightedRandomIndex(b *testing.B) {
	rand.Seed(time.Now().Unix())
	for i := 0; i < b.N; i++ {
		WeightedRandomIndex(weights)
	}
}

func BenchmarkRandomIntn(b *testing.B) {
	rand.Seed(time.Now().Unix())
	for i := 0; i < b.N; i++ {
		rand.Intn(n)
	}
}

测试结果:

[root@dev example]# go test -bench=.
goos: linux
goarch: amd64
pkg: example
BenchmarkWeightedRandomIndex-4          34809902                34.1 ns/op
BenchmarkRandomIntn-4                   51488966                23.3 ns/op
PASS
ok      example 3.340s

可以看出:加权随机索引函数比等概率随机索引函数执行效率略慢,但大致相当。