How to make while working in fixed units of time?


#1

How to make while working in fixed units of time?

for i in evrey second
to do something (working time difrent:> 0 <1 min)
end

Paul


#2

You can do that using sleep()

iter_duration = 1 # How long each iteration should last (in seconds)
for i = 1:max_iter
    tic()
    do_whatever_you_want()
    secs_remaining = iter_duration - toq()

    if secs_remaining > 0
        sleep(secs_remaining)
    end
end

#3

Nice, thx.
I understand, that no special time_iterators in Julia ?
Paul

W dniu 2017-02-05 o 14:27, Andre Manoel pisze:


#4

You could make your own like:

immutable TimeIterator{I}
    delay::Float64
    iter::I
end

"""
    timeiter(iter, delay)

Creates an iterator from another iterator, `iter`, that 
yields as soon as at least `delay`
seconds has passed since the previous yield
"""
timeiter(iter, delay) = TimeIterator(delay, iter)

Base.start(ti::TimeIterator) = start(ti.iter), time_ns()

function Base.next(ti::TimeIterator, state)
    dt = time_ns() - state[2]
    sleep(max(0.0, ti.delay - dt * 1e-9))
    val, istate = next(ti.iter, state[1])
    return val, (istate, time_ns())
end

Base.done(ti::TimeIterator, state) = done(ti.iter, state[1])

Base.size(ti::TimeIterator) = size(ti.iter)
Base.length(ti::TimeIterator) = length(ti.iter)
Base.eltype{I}(::Type{TimeIterator{I}}) = eltype(I)
Base.iteratorsize{I}(::Type{TimeIterator{I}}) = Base.iteratorsize(I)
Base.iteratoreltype{I}(::Type{TimeIterator{I}}) = Base.iteratoreltype(I)

Used as:

julia> for i in timeiter(1:5, 0.2)
           println(i, " ", Dates.Time(Dates.now()))
       end
1 21:43:26.019
2 21:43:26.22
3 21:43:26.422
4 21:43:26.623
5 21:43:26.824

julia> for i in timeiter(rand(5), 0.5)
           println(i, " ", Dates.Time(Dates.now()))
       end
0.2648576052075273 21:43:34.478
0.5878666841901361 21:43:34.98
0.9973884336226704 21:43:35.481
0.30831164754034046 21:43:35.983
0.7455394456276199 21:43:36.485

#5

Nice, big lesson for me ! Thx Kristoffer !

But my Juli dont understand

Dates.Time(Dates.now())
ERROR: UndefVarError: Time not defined

Maybe any hint :

julia> using Dates
WARNING: requiring “Dates” in module “Main” did not define a
corresponding module.

all below:


#6

It seems Dates.Time() was added in 0.6.

You could change the example to something like:

begin
t1 = time()
for i in timeiter(1:5, 0.2)
    t2 = time()
    println(i, ", Time taken: ", t2 - t1, "s")
    t1 = time()
end
end

giving

1, Time taken: 0.20130205154418945s
2, Time taken: 0.20128202438354492s
3, Time taken: 0.2012770175933838s
4, Time taken: 0.20128798484802246s
5, Time taken: 0.20125102996826172s

#7

Thx, ok, I can to use another , f.e. Dates.now()

This iterator is fery usufull but has systematical delay:
after 1000 steps (1 sek ) more then 1 sek:
like below.

I am looking for some idea to calibrate him. I must keep time for long
periods , month, years …

julia> for i in timeiter(1:10^3, 1.0)
println(i, " ",(Dates.now()))
end

1 2017-02-06T09:37:26.651
2 2017-02-06T09:37:27.652
3 2017-02-06T09:37:28.652
4 2017-02-06T09:37:29.653
5 2017-02-06T09:37:30.654
6 2017-02-06T09:37:31.655
7 2017-02-06T09:37:32.656
8 2017-02-06T09:37:33.657
9 2017-02-06T09:37:34.658
10 2017-02-06T09:37:35.659

990 2017-02-06T09:53:56.951
991 2017-02-06T09:53:57.953
992 2017-02-06T09:53:58.954
993 2017-02-06T09:53:59.954
994 2017-02-06T09:54:00.955
995 2017-02-06T09:54:01.956
996 2017-02-06T09:54:02.957
997 2017-02-06T09:54:03.958
998 2017-02-06T09:54:04.959
999 2017-02-06T09:54:05.96
1000 2017-02-06T09:54:06.961

julia> mydelay_per_ms=(1961-651)./999 # 1961 becose delay was more then
1 sek .
1.3113113113113113

Paul

W dniu 2017-02-06 o 08:37, kristoffer.carlsson pisze:


#8

Yeah you would have to tweak it to fit your needs. It was just an example.


#9

@kristoffer.carlsson had a good design in principle, just need to prevent errors from accumulating:
Don’t try to tweak it to get the correct effect by some scaling on the sleep.
Just change it to only use time_ns() once in the loop and make the increment relative to the expected time instead of the actual time (thus giving linear time steps):

function Base.next(ti::TimeIterator, state)
    dt = time_ns() - state[2]
    sleep(max(0.0, ti.delay - dt * 1e-9))
    val, istate = next(ti.iter, state[1])
    return val, (istate, state[2] + ti.delay*1e9)
end


begin
t1 = time()
tbegin = t1
    for i in timeiter(1:100, 0.2)
        t2 = time()
        println(i, ", Time taken: ", t2 - t1, "s")
        t1 = time()
    end
    tend = time()
    println("Total time taken : ", tend-tbegin, "s")
end


99, Time taken: 0.20352792739868164s
100, Time taken: 0.197404146194458s
Total time taken : 20.004184007644653s


#10

Julia also has timers:

http://docs.julialang.org/en/release-0.5/stdlib/base/?highlight=timer#Base.Timer

– mb


#11

Thx, nice idea, big thx
Paul
W dniu 2017-02-06 o 15:28, Leon Wabeke pisze:


#12

Thx, nice idea, big thx
Paul

W dniu 2017-02-06 o 15:28, Leon Wabeke pisze: