4

我正在尝试使用真实的请求频率分布来自动化服务器的功能测试。(某种负载测试,某种模拟)

我选择了Weibull分布,因为它“有点”与我观察到的分布相匹配(快速上升,快速下降但不是立即)

我使用此分布来生成在给定开始日期和结束日期之间每天应发送的请求数

我已经在 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

有什么更好的方法可以做到这一点?

4

6 回答 6

1

你为什么不试试The Grinder 3来对你的服务器进行负载测试,它带有所有这些和更多的预构建,它支持 python 作为脚本语言

于 2008-09-10T11:20:27.830 回答
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] 范围以上的所有样本中获得相应的凸起。

于 2008-09-11T10:47:06.233 回答
1

这很快而且可能不那么准确,但是如果您自己计算 PDF,那么至少您可以更轻松地在单个时间线上放置几个较小/较大的 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)
于 2008-09-11T13:40:31.730 回答
0

与其将请求数作为固定值,不如使用比例因子来代替?目前,您将请求视为有限数量,并随机分配这些请求的日期。将您的每日请求视为独立的似乎更合理。

from datetime import *
from random import *

timeline = []
scaling = 10
start_date = date(2008, 5, 1)
end_date = date(2008, 6, 1)

num_days = (end_date - start_date).days + 1
days = [start_date + timedelta(i) for i in range(num_days)]
requests = [int(scaling * weibullvariate(0.5, 2)) for i in range(num_days)]
timeline = zip(days, requests)
timeline
于 2008-09-11T08:30:23.410 回答
0

我将上面的代码重写为更短(但现在可能太模糊了?)

timeline = (start_date + timedelta(days=days) for days in count(0))
how_many_days = (end_date - start_date).days
pick_a_day = lambda _:int(how_many_days * weibullvariate(0.5, 2))
days = sorted(imap(pick_a_day, xrange(how_many_responses)))
histogram = zip(timeline, (len(list(responses)) for day, responses in groupby(days)))
print '\n'.join((d.strftime('%Y-%m-%d ') + "*" * c) for d,c in histogram)
于 2008-09-11T09:11:50.907 回答
0

另一种解决方案是使用Rpy,它将 R 的所有功能(包括许多用于分发的工具)轻松放入 Python。

于 2008-09-18T01:16:20.977 回答