tags:

views:

263

answers:

8

I am writing a test tool which places a large amount of load on a network service. I would like this tool to start with little load and gradually increase over time. I am sure that there is some triganometry which can do this sort of calculation in one line of code but I am not a math guru (yet). Is there some sort of library (or simple algorithm) which can help with this calculation?

The code would ideally take a few arguments:

  • algorithm to use (determine how quickly the value increases
  • starting value
  • ending value (maximum)
  • time (amount of time between starting and ending value)
  • step (granularity in milliseconds)

So every [step] an event would be raised indicating what the value is at that point in time.

This is an ideal implementation though, so I am open to suggestion.

Any input would be greatly appreciated, thank you :)

EDIT:

Let me be more clear ... the amount which the value increases is not linear, it is a curve.

A: 

heck just add one each time the timer goes off

Matt S.
+1  A: 

value = (endValue - StartValue) / (time / stepSize) * currentStep;

Jet
A: 

If I understood correctly, why not do this (using the "variables" you defined): You need to progress overall ending value - starting value values.

Using the time variable, you can figure out how much of an increase you want every millisecond (let's call this increase-amount).

Step just tells you how much time to "sleep" between each value you raise. Every time a new value is raised, you just do last-value + (milliseconds-since-last_step * increase-amount).

Note: I'm not sure why you need the first variable (algorithm to use), since it seems to me that its role is defined by the other variables.

Edan Maor
See my question edit for explanation about the first ("algorithm") argument.
Nippysaurus
Well in that case we'll both have to wait for someone to offer a solution, I'm not sure how to do this...
Edan Maor
A: 

Are you looking for something like this ? (in python, sorry, my C# is rusted at best)

Given you have a curve f that takes values from 0 to 1:

def my_stepper(f, start, end, time, step_size, current_step):
   x = current_step * step_size / time 
   f_1 = f(1)
   f_0 = f(0)
   y = start + (end - start) * (f(x)- f_0) / (f_1 - f_0)
   return y

for i in xrange(11):
   # increment increases over time
   print 'exp', my_stepper(math.exp, 100., 200., 10., 1., i)
   # increment decreases over time
   print 'log', my_stepper(lambda x: math.log(1+x), 100., 200., 10., 1., i)
LeMiz
A: 

Pseduo logic to your problem:

let the function be F(a+b*x) for given step x, let the starting value is start, let the ending value is end let the starting time is 0 and final time is time and InverseF is the inverse function of F.

when x=0, F(a)=start Hence a= InverseF(start) when x=time, F(a+b*time)=end, Hence b=(InverseF(end)-a)/time which reduces to b= (inverseF(end)-inverseF(start))/time

Finaly for any x=step,

value is F(a+b*step) which is nothing but

F( inverseF(start)+ (inverseF(end)-inverseF(start))/time * step )

is the answer.

For example if

F(x) is liner ie) f(x)=x

value = start+(end-start)/time*step

if F(x) is x*x, then

value = ( sqrt(start) + (sqrt(end)-sqrt(start))/time * step) * ( sqrt(start) + (sqrt(end)-sqrt(start))/time * step)

if F(x) is exp(x) then

value = Exp ( log(start) + (log(end)-log(start))/time*step )

if F(x) is log(x) then

value = Log( (exp(start) + (exp(end)-exp(start))/time*step )

and so on..

another approach without using inverse function is explained below.

let the function be a+b*F(x) for given step x, let the starting value is start, let the ending value is end let the starting time is 0 and final time is time

then a+ b * F(0) = start and a + b * F(time) = end, on solving a & b,

you will get

value = start + (end-start) / (F(time)-F(0) ) * (F(x)-F(0) )

and for a step x,

value = start + (end-start) / (F(time)-F(0) ) * (F(step)-F(0) )

and I hope, any one of the above will solve your problem..

lakshmanaraj
+3  A: 

If you desire some form of saturation (see Sigmoid function), have a look at my answer here. Another common function shape would be linear or exponential growth. Just let me know if you need one of the later.

Daniel Brückner
Sounds like a sigmoid curve is what you're looking for, a function like maxVal / (1 + e^(minVal - x)) should do, where x is the current step
SpaceghostAli
A: 

I'll reuse my answer to another question. The functions given for that answer will not spend much time doing low load, but quickly go to medium-heavy load and then increase load slower to reach maximum. If you need more values on the in the middle of the possible loads, or more values in the low load - just pass appropriate distribution function.

Given your input parameters I would call it like this:

Spread(startingValue, endingValue, time/step, x => 1-(1-x)*(1-x))

Sample algorithm functions:

FocusOnHighLoad   = x => 1-(1-x)*(1-x)
FocusOnLowLoad    = x => x * x
FocusOnMediumLoad = x => (1 + Math.Pow(x * 2 - 1, 3)) / 2

Sample output:

foreach (double load in Spread(50, 1000, 9, FocusOnHighLoad))
    Console.WriteLine("Working with {0} load", load);

Working with 50 load
Working with 272.65625 load
Working with 465.625 load
Working with 628.90625 load
Working with 762.5 load
Working with 866.40625 load
Working with 940.625 load
Working with 985.15625 load
Working with 1000 load
Juozas Kontvainis
+1  A: 

I think what you need is some easing function.

There is a set of famous easing functions created by Robert Penner. You may try to look at: Tweener transition cheat sheets which visualize Robert Penner's equations.

Robert Penner's original code should be at his webpage.

Andy Li
Those cheat sheets show exactly what I am trying to do ... display a whole lot of load profiles and allow the user to select one :) Thank you :)
Nippysaurus