joelindo
Posts: 31
Joined: Sun Aug 16, 2020 11:13 pm

1-sec != 1-sec

Mon May 03, 2021 6:56 pm

Why are my results between @100,000 and @200,0000? . . . I'm trying to find the number of times I can add two numbers together in one second.

Code: Select all

import datetime
x = 0
y = datetime.datetime.now()
sec = y.second+1
sec2 = 0
while sec2 <= sec:
    y = datetime.datetime.now()
    sec2 = y.second
    x += 1
print(sec,x,sec2)

ghp
Posts: 1970
Joined: Wed Jun 12, 2013 12:41 pm
Location: Stuttgart Germany
Contact: Website

Re: 1-sec != 1-sec

Mon May 03, 2021 7:18 pm

You start the measurement frame in the middle of a second and stop close after next+1 second starts. So your time interval is different each time.
With a slightly modified code I ran it 20 times and you see the interval length printed

Code: Select all

36 3226509 37    interval length 1.873971700668335
38 2153708 39    interval length 1.2862308025360107
40 1725832 41    interval length 1.077143669128418
42 2223634 43    interval length 1.251556396484375
44 1861549 45    interval length 1.0645787715911865
46 2343877 47    interval length 1.3598928451538086
48 3093324 49    interval length 1.7761437892913818
50 2428348 51    interval length 1.3990514278411865
52 2947491 53    interval length 1.6705169677734375
54 1760270 55    interval length 1.0613574981689453
56 1972413 57    interval length 1.1316509246826172
58 2722967 59    interval length 1.7606496810913086

Code: Select all

import datetime
import time
import random

def execute():
    x = 0
    y = datetime.datetime.now()
    sec = y.second+1
    t_sec = time.time()
    sec2 = 0
    while sec2 <= sec:
        y = datetime.datetime.now()
        sec2 = y.second
        t_sec2 = time.time()
        x += 1
    print(sec,x,sec2, "  ", "interval length", t_sec2-t_sec)

for _ in range(20):
    time.sleep( random.random() )
    execute()
For better timings, look into the timeit -module: https://docs.python.org/3/library/timeit.html

danjperron
Posts: 3790
Joined: Thu Dec 27, 2012 4:05 am
Location: Québec, Canada

Re: 1-sec != 1-sec

Mon May 03, 2021 7:22 pm

Well this mean that the you are looping between 100_000 and 200_000 times.

Second are integer so 14.99999 and 14.001 are threated the same! So you are +/- 1 second.

Also Normal behavior. Don't forget you are running linux. The operating system will interrupt your program to do something else. and sometimes it takes a little more time doing other task!

Darthux
Posts: 51
Joined: Sun Feb 14, 2021 4:12 pm

Re: 1-sec != 1-sec

Mon May 03, 2021 7:56 pm

i was having difficulty doing this using 1 second. however if you change it to 0 seconds and sleep for one second before it starts it produced various results. Once i moved it to 1 second for wait period it just runs forever.

Code: Select all

import time
seconds = 0
counter = 0
time.sleep(1)
start_time = time.monotonic()

while True:
    current_time = time.monotonic()
    elapsed_time = current_time - start_time
    if elapsed_time > seconds:
        print("Finished iterating in: " + str(int(elapsed_time))  + " seconds")
        break
    else:
        counter+=1
        print(counter)
gives me:
1. consistently around 1690 times on my Windows laptop
2. consistently around 1750 on a Raspberry Pi Pico.
3. no results on my Raspberry Pi 400, 2 or Zero w
Raspberry Pi Zero W: 2021 time lapse
Raspberry Pi Zero W: useless box in progress
Raspberry Pi 2B: Cellular environmental sensor
Raspberry Pi 3B: kodi
Raspberry Pi 3B+ : SmartMirror
Raspberry Pi 4 4G: idle
Raspberry Pi 400: develop and test

ejolson
Posts: 7245
Joined: Tue Mar 18, 2014 11:47 am

Re: 1-sec != 1-sec

Mon May 03, 2021 10:48 pm

joelindo wrote:
Mon May 03, 2021 6:56 pm
Why are my results between @100,000 and @200,0000? . . . I'm trying to find the number of times I can add two numbers together in one second.
It almost surely takes more time to query the clock than add the numbers.
Last edited by ejolson on Mon May 03, 2021 10:54 pm, edited 1 time in total.

joelindo
Posts: 31
Joined: Sun Aug 16, 2020 11:13 pm

Re: 1-sec != 1-sec

Mon May 03, 2021 10:54 pm

Thanks All !!!

kheylen25
Posts: 15
Joined: Sun Apr 11, 2021 7:58 am

Re: 1-sec != 1-sec

Thu May 06, 2021 4:38 pm

That was a pretty interesting exercise.

I came up with this code:

Code: Select all

from datetime import datetime, timedelta

def execute():
    x=0
    stoptime = datetime.now() + timedelta(seconds=1)
    while datetime.now() < stoptime:
        x += 1       
    print ("I did {} iterations in 1 second".format(x))

for _ in range(20):
    execute()
On my Windows machine (Python 3.9 and VS Code), I got pretty consistent results:

I did 1664617 iterations in 1 second
I did 1703692 iterations in 1 second
I did 1754271 iterations in 1 second
I did 1575467 iterations in 1 second
I did 1809778 iterations in 1 second
I did 1795219 iterations in 1 second
I did 1805086 iterations in 1 second
....

On the same machine, but using Python 3.8 under WSL under Ubuntu through VS Code, I got results more in the 650.000 range, over two and a half times slower.

Now I want to run this on a Pi so badly, but I got both of them working for me elsewhere at the moment :-(

ejolson
Posts: 7245
Joined: Tue Mar 18, 2014 11:47 am

Re: 1-sec != 1-sec

Thu May 06, 2021 5:32 pm

kheylen25 wrote:
Thu May 06, 2021 4:38 pm
That was a pretty interesting exercise.

I came up with this code:

Code: Select all

from datetime import datetime, timedelta

def execute():
    x=0
    stoptime = datetime.now() + timedelta(seconds=1)
    while datetime.now() < stoptime:
        x += 1       
    print ("I did {} iterations in 1 second".format(x))

for _ in range(20):
    execute()
On my Windows machine (Python 3.9 and VS Code), I got pretty consistent results:

I did 1664617 iterations in 1 second
I did 1703692 iterations in 1 second
I did 1754271 iterations in 1 second
I did 1575467 iterations in 1 second
I did 1809778 iterations in 1 second
I did 1795219 iterations in 1 second
I did 1805086 iterations in 1 second
....

On the same machine, but using Python 3.8 under WSL under Ubuntu through VS Code, I got results more in the 650.000 range, over two and a half times slower.

Now I want to run this on a Pi so badly, but I got both of them working for me elsewhere at the moment :-(
I think you need to use python3 on the Pi as the python command runs version 2 by default. I changed the code to read

Code: Select all

import time
seconds = 1
counter = 0
time.sleep(1)
start_time = time.monotonic()

while True:
    current_time = time.monotonic()
    elapsed_time = current_time - start_time
    if elapsed_time > seconds:
        print("Finished iterating in: " + str(elapsed_time) + " seconds")
        print("I did "+str(counter/elapsed_time)+" iterations per second ")
        break
    else:
        counter+=1
and obtained

Code: Select all

$ python3 sectest.py 
Finished iterating in: 1.0000003422610462 seconds
I did 618416.788340023 iterations per second 
on a Pi 4B running at stock frequencies. As stated before, this test basically checks how quickly you can fetch the time from the operating system. I think the reported speed may vary significantly depending on which side-channel mitigations have been enabled in the operating system for attacks such as Spectre and Meltdown.

kheylen25
Posts: 15
Joined: Sun Apr 11, 2021 7:58 am

Re: 1-sec != 1-sec

Thu May 06, 2021 6:13 pm

Of course you are right, however not entirely ;-)
While your code gives better results, indeed it must lose less time looking up the current time. On my system I got from around 1800000 (my code) to 2250000 (your code).

I turned the test around now, so the only thing the code does is summing 1 to x a few million times, and measure the time before and after only once. Then divide to get the number of iterations per second. At least it's the highest number I get from all I've tried, like over 6500000!
Here's the code:

Code: Select all

from datetime import datetime, timedelta

iterations = 4000000
x=0
starttime = datetime.now()
for _ in range(iterations):
    x += 1

elapsed = (datetime.now()-starttime).total_seconds()

print('I did {} iterations in {} seconds'.format(x, elapsed))
print('Which is {} iterations per second'.format(x/elapsed))


Return to “Python”