TkCanvas on windows seems slow

Hi, all,

On linux, I developed a little Tk animation using TkCanvas, and then I ran it on windows. It's much slower on windows than on linux (maybe, 5fps versus 30fps). Same machine, but ruby-1.8.4 on linux, 1.8.5 on windows.

The Windows Task Manager says the process is only using a tiny fraction of cpu, so that's not the problem.

The canvas is currently just about a dozen objects, nothing special (polygons, lines, etc.).

It does have two threads, one doing Tk.mainloop, and one sending commands to the canvas. Increasing the priority of the command thread makes it worse: Tk doesn't even seem to run--no windows. Decreasing the priority makes it even slower.

Nothing is waiting on terminal input (I know that's a problem on windows).

I tried using a TkTimer instead, but couldn't get it to work at all.

The ruby Tk animation demos seem to run fine, but they are simpler.

I realize this information is next to useless, unless someone has seen something very similar before.

Is there some setting that controls the rate at which widgets handle events?

Any ideas before I start chopping stuff out to get down to a small test case?

···

--
        vjoel : Joel VanderWerf : path berkeley edu : 510 665 3407

Joel VanderWerf wrote:

Hi, all,

On linux, I developed a little Tk animation using TkCanvas, and then I ran it on windows. It's much slower on windows than on linux (maybe, 5fps versus 30fps). Same machine, but ruby-1.8.4 on linux, 1.8.5 on windows.

The Windows Task Manager says the process is only using a tiny fraction of cpu, so that's not the problem.

The canvas is currently just about a dozen objects, nothing special (polygons, lines, etc.).

It does have two threads, one doing Tk.mainloop, and one sending commands to the canvas. Increasing the priority of the command thread makes it worse: Tk doesn't even seem to run--no windows. Decreasing the priority makes it even slower.

Nothing is waiting on terminal input (I know that's a problem on windows).

I tried using a TkTimer instead, but couldn't get it to work at all.

...

Ok, I've got a workaround. I think the problem is that the command thread (the one sending commands to the canvas) isn't getting enough chances to run.

The workaround is to fire a very frequent task from the mainloop to explicitly hand control to the command thread:

3.times do
   timer = TkTimer.new(1) do
     3.times {thread.run}
   end

   timer.start
end

The two threes was necessary on my system to get full CPU utilization. Reducing either one of them resulted in using less CPU and having a lower frame rate. The 1ms clock cycle also seems to be necessary.

With this workaround the animation runs at the same speed as on linux, about 60fps. That's a lot better than the 6 fps without the hack.

I wish I knew whether this was a problem in ruby, tkruby, or windows...

Hope this helps someone else.

···

--
        vjoel : Joel VanderWerf : path berkeley edu : 510 665 3407

Message-ID: <457EE11C.2070705@path.berkeley.edu>

With this workaround the animation runs at the same speed as on linux,
about 60fps. That's a lot better than the 6 fps without the hack.

I wish I knew whether this was a problem in ruby, tkruby, or windows...

I cannot understand how to reproduce your trouble.

# I don't have environment for development on Windows.
# And I'm so busy now.

Can the following methods help you?

  TclTkLib.set_eventloop_tick
  TclTkLib.set_no_event_wait
  TclTkLib.set_eventloop_wait

( Please see ext/tk/MANUAL_tcltklib.eng on Ruby's source tree. )

···

From: Joel VanderWerf <vjoel@path.berkeley.edu>
Subject: Re: TkCanvas on windows seems slow
Date: Wed, 13 Dec 2006 02:04:47 +0900
--
Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)

Hidetoshi NAGAI wrote:

From: Joel VanderWerf <vjoel@path.berkeley.edu>
Subject: Re: TkCanvas on windows seems slow
Date: Wed, 13 Dec 2006 02:04:47 +0900
Message-ID: <457EE11C.2070705@path.berkeley.edu>

With this workaround the animation runs at the same speed as on linux, about 60fps. That's a lot better than the 6 fps without the hack.

I wish I knew whether this was a problem in ruby, tkruby, or windows...

I cannot understand how to reproduce your trouble.

# I don't have environment for development on Windows. # And I'm so busy now.

Can the following methods help you?

  TclTkLib.set_eventloop_tick
  TclTkLib.set_no_event_wait
  TclTkLib.set_eventloop_wait

( Please see ext/tk/MANUAL_tcltklib.eng on Ruby's source tree. )

Thanks for the reference, I didn't know about those methods.

Actually, I changed some other things, and the extra task is no longer necessary. I can get an old version of the project to play with the problem more, but it's not very urgent now. If it becomes a problem again, I'll try these methods.

Another thing I found useful (for unrelated reasons) was to change thread priorities. One thread is drawing objects and the other is the mainloop thread. Every object in the animation needs to be redrawn once per unit of time. I was seeing flickering because the mainloop thread was (apparently) swapping buffers while the draw thread was iterating over the objects (that's just my guess). So I set the draw thread priority up during the iteration, and the flicker went away.

I'm glad Ruby/Tk works well with threads. It makes life easier!

···

--
        vjoel : Joel VanderWerf : path berkeley edu : 510 665 3407