canvas.show() is slow with psycho back-end and 'difficult' canvas
Hi all,
Ran into some big delays for canvas.show() function when using psycho back-end with a 'difficult' canvas.
I tested this by copying the Listing 2 example and adding Canvas3
with many randomly positioned fixation dots inspired by Example 2 here.
# Prepare canvas 1 and 2
canvas1 = canvas(exp)
canvas1.text('This is the first canvas')
canvas2 = canvas(exp)
canvas2.text('This is the second canvas')
# Prepare canvas 3 (without auto_prepare=False)
from random import randint
canvas3 = canvas()
for i in range(1000):
x = randint(0, canvas3.width)
y = randint(0, canvas3.height)
canvas3.fixdot(x, y)
# Show canvas 1
t1 = canvas1.show()
# Sleep for 95 ms to get a 100 ms delay
self.sleep(95)
# Show canvas 2
t2 = canvas2.show()
# Sleep for 95 ms to get a 100 ms delay
self.sleep(95)
# Show canvas 3
t3 = canvas3.show()
# The actual delay will be 100 ms, because stimulus
# preparation time is not included. This is good!
print 'Actual delay t2-t1: %s' % (t2-t1)
# Sadly not for the 'difficult' canvas3
print 'Actual delay t3-t2: %s' % (t3-t2)
Gives the expected output for the legacy and xpyriment back-ends, but a big delay for the 'difficult' canvas3 (t3-t2) using the psycho back-end:
psycho back-end:
Actual delay t2-t1: 100.428051515
Actual delay t3-t2: 385.974423159
legacy back-end:
Actual delay t2-t1: 96
Actual delay t3-t2: 96
xpyriment back-end:
Actual delay t2-t1: 100.0
Actual delay t3-t2: 100.0
Notes:
- I used opensesame_3.0.7-py2.7-win32-3 on Win7 64 bit with a 60Hz monitor to test this
- Because I do not use auto_prepare=False so preparing with xpyriment back-end takes long
- opensesame_3.1.0a41-py2.7-win32-1 and opensesame_2.9.7-win32-1 have the same delays
- The actual delays match with the delays I recorded with a high speed camera
Best,
Jarik
Comments
Hi Jarik,
Thanks for this benchmark.
This results from the fact the PsychoPy doesn't prepare canvases in the same way that the other back-ends do; it does create stimulus objects in advance, but they are rendered only at the moment that the canvas is shown (i.e. OpenSesame calls
draw()
andflip()
at the same time). Rendering is pretty fast, so this is usually fine; but when you have 1000+ stimuli it becomes notably slow. So that's basically inherent to how PsychoPy works.To be fair to PsychoPy, if you use psychopy directly, you can control when you call
draw()
andflip()
, and this gives you better control of the timing:But you cannot, for example, prepare multiple canvases with many objects in advance, and then show them in rapid succession. For that legacy and xpyriment are better.
Cheers!
Sebastiaan
Check out SigmundAI.eu for our OpenSesame AI assistant!
Hi Sebastiaan,
Thank you! Crystal clear now!
One minor thing is your example script prints seconds instead of milliseconds, so it should be:
Best,
Jarik
Right!
Check out SigmundAI.eu for our OpenSesame AI assistant!