Code Comments
Programming Forum and web based access to our favorite programming groups.Hi all,
I have just a question on performance. I just want to know if any as
already checked what is the fastest and also the correct way to test
these expressions (with considering strings and/or numerical values)
1:
if {$a == $b} {
..
}
2:
if {[string equal $a == $b} {
..
}
3:
and maybe a last with expr ?
Thanks in advance
Jeannot
Post Follow-up to this messageIf it's a string, I think what you want is:
if { $a eq $b } { .... }
If it's numerical, then:
if { $a == $b } { .... }
The second is needed for numbers, because { 1.0 == 1 }, but it's not
true that { 1.0 eq 1 }, since "eq" is a pure string comparison. The
first should be faster for strings, and the second for numbers (even
numbers of the same string rep?).
Robert Seeger
Jeannot wrote:
> Hi all,
>
> I have just a question on performance. I just want to know if any as
> already checked what is the fastest and also the correct way to test
> these expressions (with considering strings and/or numerical values)
>
>
> 1:
> if {$a == $b} {
> ...
> }
>
> 2:
> if {[string equal $a == $b} {
> ...
> }
>
> 3:
> and maybe a last with expr ?
>
> Thanks in advance
>
> Jeannot
Post Follow-up to this messageJeannot wrote:
> Hi all,
>
> I have just a question on performance. I just want to know if any as
> already checked what is the fastest and also the correct way to test
> these expressions (with considering strings and/or numerical values)
>
>
> 1:
> if {$a == $b} {
> ...
> }
>
> 2:
> if {[string equal $a == $b} {
> ...
> }
>
> 3:
> and maybe a last with expr ?
>
> Thanks in advance
>
> Jeannot
Just test it :)
time {if {$a == $b} { ... }} 100
time {if {[string match $a $b]} { ... }} 100
time {if {$a eq $b} { ... }} 100
Rgrds,
Khaled
Post Follow-up to this message:-) thank you I tested it and I see no differences between all for
simple comparison
with a and b = 10
and a and b = "toto"
> time {if {$a == $b} { puts t }} 10000
> time {if {[string match $a $b]} { puts t }} 10000
> time {if {[string equal $a $b]} { puts t }} 10000
> time {if {$a eq $b} { puts t }} 10000
thanks again
Khaled a écrit :
> Jeannot wrote:
>
>
>
>
>
> Just test it :)
>
> time {if {$a == $b} { ... }} 100
> time {if {[string match $a $b]} { ... }} 100
> time {if {$a eq $b} { ... }} 100
>
> Rgrds,
> Khaled
>
Post Follow-up to this messageOn Thu, 21 Apr 2005, Jeannot wrote: > :-) thank you I tested it and I see no differences between all for simple > comparison > with a and b = 10 > and a and b = "toto" Yes you do see, you just have way too high-end equipment :P You'll need to adjust the test a bit, try the following:Don't forget to take a closer look at the r? variables, too. And this one doesn't even include failing patterns. And if your high-end equipment still gives you no-difference, then pump that iteration counter (10000) up to a few million and retry. -- -Kaitzschu s="TCL ";while true;do echo -en "\r$s";s=${s:1:${#s}}${s:0:1};sleep .1;donecode:
proc iu {a b} { set r1 0 set r2 0 set r3 0 set r4 0 set t1 [lindex [split [time { time {if {$a == $b} {set r1 1}} 10000}] { }] 0] set t2 [lindex [split [time { time {if {[string match $a $b]} {set r2 1}} 10000}] { }] 0] set t3 [lindex [split [time { time {if {[string equal $a $b]} {set r3 1}} 10000}] { }] 0] set t4 [lindex [split [time { time {if {$a eq $b} {set r4 1}} 10000}] { }] 0] puts "$a $b ->\t==: $t1 /$r1\tsm: $t2 /$r2\tse: $t3 /$r3\teq: $t4 /$r4" } iu 10 10 iu toto toto iu {a[bc]d} {abd} iu 011 9 iu 0xff 255
Post Follow-up to this messageOk thanks, I will try Kaitzschu a écrit : > On Thu, 21 Apr 2005, Jeannot wrote: > > > > Yes you do see, you just have way too high-end equipment :P > You'll need to adjust the test a bit, try the following: > >> > Don't forget to take a closer look at the r? variables, too. And this > one doesn't even include failing patterns. And if your high-end > equipment still gives you no-difference, then pump that iteration > counter (10000) up to a few million and retry. >code:
> > proc iu {a b} { > set r1 0 > set r2 0 > set r3 0 > set r4 0 > set t1 [lindex [split [time { > time {if {$a == $b} {set r1 1}} 10000}] { }] 0] > set t2 [lindex [split [time { > time {if {[string match $a $b]} {set r2 1}} 10000}] { }] 0] > set t3 [lindex [split [time { > time {if {[string equal $a $b]} {set r3 1}} 10000}] { }] 0] > set t4 [lindex [split [time { > time {if {$a eq $b} {set r4 1}} 10000}] { }] 0] > puts "$a $b ->\t==: $t1 /$r1\tsm: $t2 /$r2\tse: $t3 /$r3\teq: $t4 /$r4" > } > > iu 10 10 > iu toto toto > iu {a[bc]d} {abd} > iu 011 9 > iu 0xff 255 > >
Post Follow-up to this messageHhm - using "==" is not really a slow down, when comparing strings, but it can be dangerous if the strings are numbers, that must be compared as strings not as numbers, because these string will be converted numbers, and than those numbers will be compared. What's about the internal object types? Should the "==" operator be faster if e.g. the strings "0xff" and "255" have the internal type "integer" instead of "string"? I changed the code above to (added "string compare"):And I run following tests:code:
proc iu {a b} { global repeats; # to prevent shimmering # set a1 [set a2 [set a3 [set a4 [set a5 $a]]]]; set b1 [set b2 [set b3 [set b4 [set b5 $b]]]]; set r1 [set r2 [set r3 [set r4 [set r5 0]]]]; set t1 [lindex [split [time {time \ {if {$a1 == $b1} {set r1 1}} $repeats}] { }] 0] set t2 [lindex [split [time {time \ {if {[string match $a1 $b1] == 1} {set r2 1}} $repeats}] { }] 0] set t3 [lindex [split [time {time \ {if {[string equal $a1 $b1] == 1} {set r3 1}} $repeats}] { }] 0] set t4 [lindex [split [time {time \ {if {[string compare $a1 $b1] == 0} {set r4 1}} $repeats}] { }] 0] set t5 [lindex [split [time {time \ {if {$a1 eq $b1} {set r5 1}} $repeats}] { }] 0] puts "$a $b -> ==: ${t1}/$r1 sm: ${t2}/$r2 se: ${t3}/$r3 sc: ${t4}/$r4 eq: ${t4}/$r4" } set repeats 50000;[result] 10 10 -> ==: 64364/1 sm: 75869/1 se: 70262/1 sc: 72300/1 eq: 72300/1 toto toto -> ==: 99066/1 sm: 79240/1 se: 72271/1 sc: 72965/1 eq: 72965/1 a[bc]d abd -> ==: 86288/0 sm: 77563/1 se: 58838/0 sc: 62603/0 eq: 62603/0 011 9 -> ==: 61042/1 sm: 59206/0 se: 58202/0 sc: 59140/0 eq: 59140/0 0xff 255 -> ==: 61511/1 sm: 59427/0 se: 58665/0 sc: 59254/0 eq: 59254/0 [/result]code:
# "simple" examples comparing always "strings" # iu 10 10 iu toto toto iu {a[bc]d} {abd} iu 011 9 iu 0xff 255[result] 10 10 -> ==: 61903/1 sm: 73881/1 se: 70868/1 sc: 72999/1 eq: 72999/1 10 100 -> ==: 52354/0 sm: 62127/0 se: 60392/0 sc: 61416/0 eq: 61416/0 100 100 -> ==: 60781/1 sm: 77318/1 se: 69184/1 sc: 70191/1 eq: 70191/1 [/result]code:
# examples with "typed" "strings" # set a 10; set b 10; set c [expr {$a * $b}]; iu $a $b iu $a $c iu $c $c[result] 10 10 -> ==: 61861/1 sm: 73981/1 se: 71953/1 sc: 72072/1 eq: 72072/1 10 100 -> ==: 50234/0 sm: 70064/0 se: 58949/0 sc: 60662/0 eq: 60662/0 100 100 -> ==: 59595/1 sm: 76337/1 se: 69011/1 sc: 69256/1 eq: 69256/1 [/result]code:
set a [string range $a 0 end]; set b [string range $b 0 end]; set c [string range $c 0 end]; iu $a $b iu $a $c iu $c $c[result] 255 255 -> ==: 60616/1 sm: 76223/1 se: 71211/1 sc: 73050/1 eq: 73050/1 255.0 255 -> ==: 62439/1 sm: 68898/0 se: 58965/0 sc: 60713/0 eq: 60713/0 [/result] So I'm not really able to suggest the usage of "==" or "eq" only using speed as judgement! But I would always suggest to clarify code to use "==" only for number comparisons and "eq" only for string comparison - no matter what is quicker or not! A bit surprising for me was, that "eq" is as fast as "string compare". Why this? Best regards, Martin Lemburg UGS The PLM Companycode:
iu [expr {int(0xff)}] [expr {int(255)}]; iu [expr {double(0xff)}] [expr {int(255)}];
Post Follow-up to this messageMartinLemburg@UGS wrote: > # to prevent shimmering > # > set a1 [set a2 [set a3 [set a4 [set a5 $a]]]]; > set b1 [set b2 [set b3 [set b4 [set b5 $b]]]]; Why do you imagine this will prevent shimmering? -- | Don Porter Mathematical and Computational Sciences Division | | donald.porter@nist.gov Information Technology Laboratory | | http://math.nist.gov/~DPorter/ NIST | |_______________________________________ _______________________________|
Post Follow-up to this messageAccording to MartinLemburg@UGS <martin.lemburg.ugs@gmx.net>: :Hhm - using "==" is not really a slow down, when comparing strings, but :it can be dangerous if the strings are numbers, that must be compared :as strings not as numbers, because these string will be converted :numbers, and than those numbers will be compared. Also, most performance testing should be done, not as plain commands, but invoking a proc containing the commands. This is because otherwise, it is my understanding that you don't get the byte compilation. -- <URL: http://wiki.tcl.tk/ > MP3 ID tag repair < http://www.fixtunes.com/?C=17038[/<...rg/NET/lvirden/ >
Post Follow-up to this messageOk, I changed the code to:I tried following:code:
proc t1 {a b} { if {$a == $b} { return 1; } return 0; } proc t2 {a b} { if {[string match $a $b] == 1} { return 1; } return 0; } proc t3 {a b} { if {[string equal $a $b] == 1} { return 1; } return 0; } proc t4 {a b} { if {[string compare $a $b] == 0} { return 1; } return 0; } proc t5 {a b} { if {$a eq $b} { return 1; } return 0; } proc iu {a b} { global repeats; set r1 [t1 $a $b]; set r2 [t2 $a $b]; set r3 [t3 $a $b]; set r4 [t4 $a $b]; set r5 [t5 $a $b]; set t1 [lindex [time {t1 $a $b} $repeats] 0] set t2 [lindex [time {t2 $a $b} $repeats] 0] set t3 [lindex [time {t3 $a $b} $repeats] 0] set t4 [lindex [time {t4 $a $b} $repeats] 0] set t5 [lindex [time {t5 $a $b} $repeats] 0] puts "$a $b: == ${t1}/$r1 sm ${t2}/$r2 se ${t3}/$r3 sc ${t4}/$r4 eq ${t4}/$r4" }And I got following results: 10 10: == 3/1 sm 3/1 se 3/1 sc 3/1 eq 3/1 toto toto: == 4/1 sm 3/1 se 3/1 sc 3/1 eq 3/1 a[bc]d abd: == 3/0 sm 3/1 se 3/0 sc 3/0 eq 3/0 011 9: == 2/1 sm 3/0 se 3/0 sc 3/0 eq 3/0 0xff 255: == 3/1 sm 3/0 se 3/0 sc 3/0 eq 3/0 10 10: == 3/1 sm 3/1 se 3/1 sc 3/1 eq 3/1 10 100: == 3/0 sm 3/0 se 3/0 sc 3/0 eq 3/0 100 100: == 2/1 sm 3/1 se 3/1 sc 3/1 eq 3/1 10 10: == 3/1 sm 3/1 se 3/1 sc 3/1 eq 3/1 10 100: == 3/0 sm 3/0 se 3/0 sc 3/0 eq 3/0 100 100: == 2/1 sm 3/1 se 3/1 sc 3/1 eq 3/1 255 255: == 3/1 sm 3/1 se 3/1 sc 3/1 eq 3/1 255.0 255: == 3/1 sm 3/0 se 3/0 sc 3/0 eq 3/0 Now every test is a procedure and should be byte compiled. And I changed the evaluation time measurement from: set t1 [lindex [split [time {time {if {$a1 == $b1} {set r1 1}} $repeats}] { }] 0]; to set t1 [lindex [time {t1 $a $b} $repeats] 0]; The differences in the consumed time per evaluation are so small, that it doesn't really make sense to discuss about the performance. IMHO it is still the question, what I like to compare! If its about a numerical comparison, than the "==" operator has to be used! Is it about a string comparison, than it's about the "eq" operator! Right?! Best Regards, Martin Lemburg UGS The PLM Companycode:
iu 10 10 iu toto toto iu {a[bc]d} {abd} iu 011 9 iu 0xff 255 set a 10; set b 10; set c [expr {$a * $b}]; iu $a $b iu $a $c iu $c $c set a [string range $a 0 end]; set b [string range $b 0 end]; set c [string range $c 0 end]; iu $a $b iu $a $c iu $c $c iu [expr {int(0xff)}] [expr {int(255)}]; iu [expr {double(0xff)}] [expr {int(255)}];
Post Follow-up to this messagePowered by vBulletin
Copyright 2000-2006 Jelsoft Enterprises Limited.