如何为给定的概率分布生成直方图(用于功能测试服务器)?
我正在尝试自动化测试一个服务器的功能,使用一种比较真实的请求频率分布。(有点像负载测试,也有点像模拟)
我选择了威布尔分布,因为它“有点”符合我观察到的请求分布(请求量快速上升,然后又迅速下降,但不是立刻)
我用这个分布来生成在一个指定的开始和结束日期之间,每天应该发送的请求数量
我在Python里拼凑了一个算法,虽然能工作,但感觉有点笨拙:
how_many_days = (end_date - start_date).days
freqs = defaultdict(int)
for x in xrange(how_many_responses):
freqs[int(how_many_days * weibullvariate(0.5, 2))] += 1
timeline = []
day = start_date
for i,freq in sorted(freqs.iteritems()):
timeline.append((day, freq))
day += timedelta(days=1)
return timeline
还有什么更好的方法可以做到这一点吗?
6 个回答
1
下面是你最后四行代码的一个稍微长一点但可能更易读的版本:
samples = [0 for i in xrange(how_many_days + 1)]
for s in xrange(how_many_responses):
samples[min(int(how_many_days * weibullvariate(0.5, 2)), how_many_days)] += 1
histogram = zip(timeline, samples)
print '\n'.join((d.strftime('%Y-%m-%d ') + "*" * c) for d,c in histogram)
这个代码总是会去掉在指定日期范围内的样本,但在时间线的末尾会因为所有超出[0, 1]范围的样本而出现一个相应的增加。
1
你可以试试The Grinder 3来对你的服务器进行负载测试。这个工具已经内置了很多功能,支持用Python来写脚本,非常方便。
1
这段话说的是,虽然这个方法可能不太准确,但如果你自己计算PDF(概率密度函数),那么你就能更方便地把几个小的或大的放在同一个时间线上。这里提到的dev
是高斯噪声中的标准差,它控制了粗糙程度。需要注意的是,这并不是生成你想要的东西的“正确”方法,但它比较简单。
import math
from datetime import datetime, timedelta, date
from random import gauss
how_many_responses = 1000
start_date = date(2008, 5, 1)
end_date = date(2008, 6, 1)
num_days = (end_date - start_date).days + 1
timeline = [start_date + timedelta(i) for i in xrange(num_days)]
def weibull(x, k, l):
return (k / l) * (x / l)**(k-1) * math.e**(-(x/l)**k)
dev = 0.1
samples = [i * 1.25/(num_days-1) for i in range(num_days)]
probs = [weibull(i, 2, 0.5) for i in samples]
noise = [gauss(0, dev) for i in samples]
simdata = [max(0., e + n) for (e, n) in zip(probs, noise)]
events = [int(p * (how_many_responses / sum(probs))) for p in simdata]
histogram = zip(timeline, events)
print '\n'.join((d.strftime('%Y-%m-%d ') + "*" * c) for d,c in histogram)