Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Tk really slow on Windows 10?

877 views
Skip to first unread message

blacksqr

unread,
Dec 18, 2019, 3:33:31 PM12/18/19
to
I'm developing a modestly ambitious cross-platform Tcl/Tk app using version 8.6.8.

It runs like lightning on Ubuntu Linux, but the UI is noticeably sluggish on Windows 10.

I know that Windows generally underperforms Linux, but the timing disparities in my case seem excessive. I've used the Tcllib profiler package to find slowdowns and separate out network and db operations from the pure Tk operations. In some cases Tk operations on Windows are an order of magnitude slower.

For example, I'm using tablelist widgets in some places, with relatively little data displayed, and still the most time-consuming procs from the tablelist package can take ten times longer to run on Win10 than Linux.

I've timed widget loading multiple times per session to factor out initial loading time penalties, and the disparities persist.

It's sufficiently problematic that the project's sponsor is worried about ultimate usability by the intended clients, thus it may be an existential threat to the success of the project.

Is this a known problem? Is it something that just has to be lived with? Can anything be done to mitigate?

Rich

unread,
Dec 18, 2019, 4:06:08 PM12/18/19
to
blacksqr <stephen...@alum.mit.edu> wrote:
> I'm developing a modestly ambitious cross-platform Tcl/Tk app using
> version 8.6.8.
>
> It runs like lightning on Ubuntu Linux, but the UI is noticeably
> sluggish on Windows 10.
>
> I know that Windows generally underperforms Linux, but the timing
> disparities in my case seem excessive.
> ...
> For example, I'm using tablelist widgets in some places, with
> relatively little data displayed, and still the most time-consuming
> procs from the tablelist package can take ten times longer to run on
> Win10 than Linux.
>
> Is this a known problem?

My 2 cents are I've never noticed a sluggish issue on W10 vs. Linux
(myself).

With that said, I have no W10 scripts that I've built for myself that
use tablelist, so if there is a tablelist specific issue I would not
have noticed it.

Is your script doing other stuff (network accesses, db accesses) that
might be the real cause due to differences in environments?

You might want to try creating a minimal version that still exhibits
the issue by deleting, one by one, small bits of code and checking if
the slowdowns are still present. If after a deletion you find w10 is
now just as fast as under Linux, then the part you deleted was slowing
down w10 but not Linux. Then you'll have something specific to
investigate.

Nicolas

unread,
Dec 19, 2019, 12:36:35 AM12/19/19
to
Hi,
you may want to use Tk 8.6.10
Csaba recently post a tableList update and the log says :

What is new in Tablelist 6.8?
-----------------------------

1. Updated and significantly improved the support for Windows 10.

++

nemethi

unread,
Dec 19, 2019, 4:03:49 AM12/19/19
to
Am 19.12.19 um 06:36 schrieb Nicolas:
Those improvements are appearance-related only. They make sure the look
& feel will be native again. Some parts of the original code were no
longer compatible with newer releases of Windows 10.

--
Csaba Nemethi http://www.nemethi.de mailto:csaba....@t-online.de

Alexandru

unread,
Dec 19, 2019, 7:58:53 AM12/19/19
to
I can confirm performance issues with tablelist when using lots of columns.
I don't know, if this is only Windows specific.

Harald Oehlmann

unread,
Dec 19, 2019, 8:45:32 AM12/19/19
to
Dear Blacksqr,

I am a Windows TCL developper.
It is always amazing for me to start my own programs in a VM with Linux.
It feels at least 2 times faster and the responsiveness is amazing.
So, yes, Linux is faster than Windows for Tk. This has always been the
case (I am in the boat since 1997).

I would not call it a problem.

Thank you,
Harald

nemethi

unread,
Dec 19, 2019, 9:23:26 AM12/19/19
to
Am 19.12.19 um 13:58 schrieb Alexandru:
In general, using lots (i.e., several dozens) of columns has a negative
impact on the tablelist performance. However, on Windows the slowdown
is about 10 times worse than on X11. I was not able to find the reason
for this drastic difference.

blacksqr

unread,
Dec 19, 2019, 10:29:52 AM12/19/19
to
In general, using lots (i.e., several dozens) of columns has a negative
> impact on the tablelist performance. However, on Windows the slowdown
> is about 10 times worse than on X11. I was not able to find the reason
> for this drastic difference.

Thanks for you response... I usually use only a few and never more than a dozen columns in a tablelist.

I didn't mean to single tablelist widgets out -- the slowdown manifests across Tk. Tablelist procs were just the easiest to spot in my performance profiling.

blacksqr

unread,
Dec 19, 2019, 10:30:44 AM12/19/19
to
Thanks for your response, for my sanity if nothing else.

tombert

unread,
Dec 19, 2019, 4:15:42 PM12/19/19
to
Windows in general is slower than linux, but I would not say it's excessive. Most importantly for me, the main process blocks if the GUI is grabbed.

Do this:

Open a Console on Windows using wish. Type the command:

> time {after 100; update; puts [incr index]} 100

Now grab the toplevel with the mouse. You will see the index stops counting.
Do the same on linux and you will see the index continuous counting.

You might want to know - the GUI is even twice as fast if you use Wayland. Starting Ubuntu 18 you can use that.

Andreas Leitgeb

unread,
Feb 27, 2020, 9:59:42 AM2/27/20
to
Sorry if I'm "necroposting" here... (orig was from Dec 2019)

tombert <tomber...@live.at> wrote:
> Windows in general is slower than linux, but I would not say it's
> excessive.

I'd like to share a recent experience from some user of my application.

I'm developing my app on Linux, running it in a Terminal and watching
lots of debug-output in Terminal.

Some co-worker runs it on Windows 10 with "console show" added to his
app config, and it runs decently fast, too.

Another co-worker did almost the same, but isn't interested in the
console. It was noticeably slower there.

In the end, I added a switch to enable/disable even calling "puts"
for debug-messages, and those with switch off no longer complain.

Maybe, Windows 10's "/dev/null" (whereever stdout goes for GUI apps
that don't replace "puts" by some console-appender) is rather slow.

Alexandru

unread,
Feb 27, 2020, 1:38:14 PM2/27/20
to
I can confirm this: using puts on Windows console makes performance 100x slower than without. i thought this is normal and system independent.

Rich

unread,
Feb 27, 2020, 1:43:28 PM2/27/20
to
It is 'normal', but it only occurs on system that redirect
stdout/stderr into the Tk console (i.e., generally windows). Systems
with that do not redirect the stdout/stderr channels do not see the
performance degradation (Linux). I've no idea re. MacOS which side it
falls into. MacOS is a real Unix underneath, so it might fall on the
Linux side, but a Mac user would need to confirm.

tedbr...@gmail.com

unread,
Feb 27, 2020, 1:54:50 PM2/27/20
to
On Thursday, February 27, 2020 at 6:59:42 AM UTC-8, Andreas Leitgeb wrote:
> Some co-worker runs it on Windows 10 with "console show" added to his
> app config, and it runs decently fast, too.
>
> Another co-worker did almost the same, but isn't interested in the
> console. It was noticeably slower there.
>

I find that it's much faster if the console is open
AND you've done at least 1 update. In the below, if you
enable the update, it will run about 10x faster.

Using update here, doesn't work if the console is not yet open.
Perhaps the update doesn't do anything if the console is not open.

console show
#update

set last 1500
puts [time {
for {set m 1} {$m < $last} {incr m} {
puts "m is $m ============================="
}
}]
console show

Rich

unread,
Feb 27, 2020, 2:15:25 PM2/27/20
to
Better for increased performance is to create a puts you can turn off.
I.e.:

At the top of your script:

set debug 1

if {$debug} {
proc dbg {args} {}
} else {
proc dbg {args} { puts [join $args] }
}

And then, later, when wanting to output debugging data to the console:


dbg This is a debug statement var = $var x = $y y = $y

And then, for normal users, set "debug" to "0" at the start of the
script to 'turn off' all the debugging statements.

Substitute your preferred name for the "dbg" proc of course.

This also has the advantage that you can turn off the console debug
output yourself with a one line change. If you want 'configurability'
then obtain the on/off state from elsewhere (file, database, UI
widget).

tedbr...@gmail.com

unread,
Feb 27, 2020, 3:21:16 PM2/27/20
to
On Wednesday, December 18, 2019 at 12:33:31 PM UTC-8, blacksqr wrote:
> It runs like lightning on Ubuntu Linux, but the UI is noticeably sluggish on Windows 10.


I also found that the console can be quite slow on
Androwish, where I've used the below hack. Note this
is modifying console code that may not work in
later versions of tcl/tk. I've tested up to 8.6.9.


The console is my primary debugging tool, and so I've
also used several tricks described here,

https://wiki.tcl-lang.org/page/console


Below, I also increase the number of lines in the
console window. And one command I add to the console is
to pause and unpause scrolling, which can also
help performance. That's what the do_scroll variable is
all about. Left at 1, as below, and it doesn't do anything.

Obviously, this hack may be a problem with other code
since this is running an [after] event which keeps
repeating every 200 ms.

This also can speed up the console on windows. It works
by not doing the [.console see insert] on every puts.

#------------------------------
console eval {
set ::tk::console::maxLines 5000 ;# normally only 600

set ::tk::console_flag 0
set ::tk::do_scroll 1
proc ::tk::console_hack {} {

if {$::tk::console_flag && $::tk::do_scroll} {
.console mark set insert end
.console see insert
set ::tk::console_flag 0
}
after 200 ::tk::console_hack
}
proc ::tk::ConsoleOutput {dest string} {
set w .console
$w insert output $string $dest
::tk::console::ConstrainBuffer $w $::tk::console::maxLines
set ::tk::console_flag 1
}
after 200 ::tk::console_hack

}

Robert Heller

unread,
Feb 27, 2020, 3:22:20 PM2/27/20
to
At Thu, 27 Feb 2020 19:15:21 -0000 (UTC) Rich <ri...@example.invalid> wrote:

>
> tedbr...@gmail.com wrote:
> > On Thursday, February 27, 2020 at 6:59:42 AM UTC-8, Andreas Leitgeb wrote:
> >> Some co-worker runs it on Windows 10 with "console show" added to his
> >> app config, and it runs decently fast, too.
> >>
> >> Another co-worker did almost the same, but isn't interested in the
> >> console. It was noticeably slower there.
> >>
> >
> > I find that it's much faster if the console is open
> > AND you've done at least 1 update. In the below, if you
> > enable the update, it will run about 10x faster.
> >
> > Using update here, doesn't work if the console is not yet open.
> > Perhaps the update doesn't do anything if the console is not open.
> >
> > console show
> > #update
> >
> > set last 1500
> > puts [time {
> > for {set m 1} {$m < $last} {incr m} {
> > puts "m is $m ============================="
> > }
> > }]
> > console show
> >
>
> Better for increased performance is to create a puts you can turn off.
> I.e.:
>
> At the top of your script:
>
> set debug 1
>
> if {$debug} {
# Should be (for debug == 0 meaning no debug output):
if {!$debug} {
> proc dbg {args} {}
> } else {
> proc dbg {args} { puts [join $args] }
> }
>
> And then, later, when wanting to output debugging data to the console:
>
>
> dbg This is a debug statement var = $var x = $y y = $y
>
> And then, for normal users, set "debug" to "0" at the start of the
> script to 'turn off' all the debugging statements.
>
> Substitute your preferred name for the "dbg" proc of course.
>
> This also has the advantage that you can turn off the console debug
> output yourself with a one line change. If you want 'configurability'
> then obtain the on/off state from elsewhere (file, database, UI
> widget).
>

--
Robert Heller -- 978-544-6933 Cell: 413-658-7953
Deepwoods Software -- Custom Software Services
http://www.deepsoft.com/ -- Linux Administration Services
hel...@deepsoft.com -- Webhosting Services

Robert Heller

unread,
Feb 27, 2020, 3:22:20 PM2/27/20
to
I believe stdout/stderr == Terminal on MacOSX (Terminal is just like any
XTerm-ish window under Linux -- it uses a /dev/tty like device (a kernel
implemented psuedo / virtual tty device). MacOSX Tk, like Linux has no
"console" in the sense that MS-Windows has. Yes, you can fire up a console if
you really want one, but for typical debugging, one opens up the Tk app either
from the Terminal shell or uses "Open with Terminal" if starting from a
launcher icon or a desktop icon, just like Linux (or I expect *BSD or other
"real" UNIX -- eg Solaris, etc.).

Rich

unread,
Feb 27, 2020, 3:45:01 PM2/27/20
to
Oops, yes you are correct. The dangers of typing code directly into a
Usenet posting.

Eric

unread,
Feb 28, 2020, 2:17:21 AM2/28/20
to
Hi,

not really system dependent, the problem is in the text widget which wraps the inserted lines, and when not displayed, does this in a 1-pixel wide text widget.
See https://core.tcl-lang.org/tk/tktview/ff8a1e55a2b8714d2390.
The fix is working, but is incomplete because the console does a "see end" and the text widget code also update the scrollbar information.

Eric

tedbr...@gmail.com

unread,
Feb 28, 2020, 1:24:18 PM2/28/20
to
On Thursday, February 27, 2020 at 11:17:21 PM UTC-8, Eric wrote:


> not really system dependent, the problem is in the text widget which wraps the inserted lines, and when not displayed, does this in a 1-pixel wide text widget.
> See https://core.tcl-lang.org/tk/tktview/ff8a1e55a2b8714d2390.
> The fix is working, but is incomplete because the console does a "see end" and the text widget code also update the scrollbar information.
>
> Eric

That would explain why an initial [console show] followed by
an [update] does speed it up somewhat, as that ticket only
addressed the “insert” performance, but not from “see”.

Doing a “show, update, hide” at the program start would solve
the window mapping issue, if there was a way to avoid the
visual flashing of the console appearing for an instant.

And, if there was also a better way to avoid doing unneeded
“see end”'s than a repeating timer (mine limits that to 5/second)
the console performance would be fixed. But also if “see index”
could self limit that would solve any other use of “see” in a
text widget. A user is unlikely to be able to “see” more than 5-10
updates per second anyway.

I suppose it could use the clock to limit itself, but then how
can the last one be “flushed” out without using an [after] timer.

BTW, I can do 100,000 [puts] per second when combining the code
from my previous 2 posts.

blacksqr

unread,
Mar 2, 2020, 11:01:34 AM3/2/20
to
On Thursday, February 27, 2020 at 8:59:42 AM UTC-6, Andreas Leitgeb wrote:
> Sorry if I'm "necroposting" here... (orig was from Dec 2019)

Nope, still reading and absorbing your comments and those following. I will try to apply them to my problems...

tombert

unread,
Mar 5, 2020, 4:59:27 AM3/5/20
to
would be interesting if you came to a conclusion?

blacksqr

unread,
Mar 7, 2020, 10:14:33 PM3/7/20
to
Work is ongoing.
0 new messages