2008-09-10 3 views
3

Ich versuche, Funktionstests eines Servers mit einer realistischen Häufigkeitsverteilung von Anfragen zu automatisieren. (Art von Lasttests, eine Art Simulation)Wie erzeuge ich ein Histogramm für eine gegebene Wahrscheinlichkeitsverteilung (für den Funktionstest eines Servers)?

IIIIIIVV die Weibull Verteilung, wie es „Art“ entspricht die Verteilung ich beobachtet habe (Rampen schnell, fällt schnell ab, aber nicht sofort)

ich benutze diese Verteilung die Anzahl der Anfragen zu generieren, die jeden Tag zwischen einem bestimmten Start- und Enddatum

gesendet werden sollen

ich zusammen diese Art von Arbeiten einem Algorithmus in Python gehackt habe, aber es fühlt sich kludgy:

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 

Welche besseren Möglichkeiten gibt es, dies zu tun?

+0

Dieser Algorithmus gibt immer die erwartete Anzahl der Antworten zurück, passt aber normalerweise nicht genau zwischen Anfangs- und Enddatum. Ich bin mir nicht sicher, ob dies möglich ist, wenn ich nicht manuell mit den Frequenzen herumhaue. –

+0

Es ist nicht garantiert, dass sie zwischen Start- und Enddatum passen, da Sie eine Wahrscheinlichkeitsverteilung mit unendlicher Unterstützung verwenden. Solange Sie die aus der Distribution zurückgegebene Zufallszahl unverändert als Schlüssel verwenden, haben Sie dieses Problem. – Kai

Antwort

1

Das ist schnell und wahrscheinlich nicht so genau, aber wenn Sie das PDF selbst berechnen, machen Sie es zumindest einfacher, mehrere kleinere/größere auf einer einzigen Timeline zu legen. dev ist die Standardabweichung im Guassian-Rauschen, die die Rauheit steuert. Beachten Sie, dass dies nicht die 'richtige' Möglichkeit ist zu generieren, was Sie wollen, aber es ist einfach.

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) 
+0

Großartig sieht die Verteilung viel besser aus als die, die durch Simulation erzeugt wurde. –

1

Warum Sie The Grinder 3 zu laden testen Sie Ihren Server nicht versuchen, es mit all dies kommt und mehr vorkompilierte und unterstützt Python als Skriptsprache

+0

Nun leider, diese Funktion wird in einigen Funktionstests auch verwendet werden, so würde ich gerne alles in der Familie so viel wie möglich behalten. Vielleicht ist Simulation eine bessere Beschreibung als Belastungstest –

0

Statt die Anzahl der Anfragen als festen Wert des Gebens, warum nicht stattdessen einen Skalierungsfaktor verwenden? Im Moment behandeln Sie Anfragen als eine begrenzte Menge und randomisieren die Tage, an denen diese Anfragen fallen. Es erscheint vernünftiger, Ihre Anfragen pro Tag als unabhängig zu behandeln.

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 
+0

Diese Funktion scheint nicht die Form zu produzieren, die ich suche.Wenn Sie im Wikipedia-Artikel nachsehen, wählte ich die rote Kurve, die schnell ansteigt und dann im Laufe der Zeit abbricht, wie es scheint, um Seitenansichten zu modellieren, anfangs hoch, aber dann verlieren die Leute das Interesse an dem neuen Inhalt im Laufe der Zeit. –

+0

In der Tat der ganze Punkt (aus meiner Sicht :-) ist, dass die Anzahl der Anfragen hängt von dem Tag ab. Ich versuche nicht nur zufällige Lasten über einen bestimmten Zeitraum hinweg zu modellieren. –

+0

Okay, aber was Sie jetzt tun, ist nur die Verteilung zu approximieren. Warum nicht die Distribution selbst oder die Distribution plus etwas Rauschen? So wie es aussieht, modellieren Sie einen verlaufsabhängigen Prozess ohne Verwendung eines Verlaufs. – Kai

0

schrieb ich den Code oben kürzer (aber vielleicht jetzt auch verschleierten es?)

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) 
+0

sind die Einfuhr für die Funktion oben: von Datumzeit import DATETIME Timedelta Zufälliges import weibullvariate aus itertools importieren IMAP, zählen, GROUPBY how_many_responses = 100 start_date = date (2008, 5, 1) end_date = date (2008, 6, 1) –

1

Etwas länger, aber wahrscheinlich besser lesbar Nacharbeit Ihrer letzten vier Zeilen:

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) 

Dadurch werden die Samples immer innerhalb des Datumsbereichs abgelegt. Sie erhalten jedoch einen entsprechenden Bump am Ende der Timeline von allen Samples, die über dem [0, 1] -Bereich liegen.

+0

Schön, ich mag es. Ich versuche immer, Dinge in Iteratoren zu stopfen, aber das ist definitiv einfacher zu lesen :-) –

0

Eine andere Lösung ist Rpy zu verwenden, die die gesamte Leistung von R (darunter viele Werkzeuge für die Distributionen), leicht in Python setzt.

Verwandte Themen