Discussion:
good to know: tcl static "regexp" is faster than tcl "string" operation
Add Reply
aotto1968
2024-12-31 10:19:34 UTC
Reply
Permalink
#!/usr/bin/env tclsh

proc test-1 { val } {
if {[regexp ^:: $val]} {
return true
} else {
return false
}
}

proc test-2 { val } {
if {[string range $val 0 1] eq "::"} {
return true
} else {
return false
}
}

set num 100000
puts 1=[time {test-1 ::otto} $num]
puts 2=[time {test-1 otto} $num]
puts 3=[time {test-2 ::otto} $num]
puts 4=[time {test-2 otto} $num]
./sbin/time-check.tcl
1=1.26311 microseconds per iteration
2=1.09152 microseconds per iteration
3=1.44028 microseconds per iteration
4=1.43917 microseconds per iteration
Rich
2024-12-31 13:46:44 UTC
Reply
Permalink
Post by aotto1968
#!/usr/bin/env tclsh
proc test-1 { val } {
if {[regexp ^:: $val]} {
return true
} else {
return false
}
}
proc test-2 { val } {
if {[string range $val 0 1] eq "::"} {
return true
} else {
return false
}
}
set num 100000
puts 1=[time {test-1 ::otto} $num]
puts 2=[time {test-1 otto} $num]
puts 3=[time {test-2 ::otto} $num]
puts 4=[time {test-2 otto} $num]
./sbin/time-check.tcl
1=1.26311 microseconds per iteration
2=1.09152 microseconds per iteration
3=1.44028 microseconds per iteration
4=1.43917 microseconds per iteration
But neither is quite as fast as string match (athough regex is close):

$ cat time-check.tcl
#!/usr/bin/env tclsh

proc test-1 { val } {
if {[regexp ^:: $val]} {
return true
} else {
return false
}
}

proc test-2 { val } {
if {[string range $val 0 1] eq "::"} {
return true
} else {
return false
}
}

proc test-3 { val } {
return [string match ::* $val]
}

set num 100000
puts 1=[time {test-1 ::otto} $num]
puts 2=[time {test-1 otto} $num]
puts 3=[time {test-2 ::otto} $num]
puts 4=[time {test-2 otto} $num]
puts 5=[time {test-3 ::otto} $num]
puts 6=[time {test-3 otto} $num]

$ ./time-check.tcl
1=0.45252 microseconds per iteration
2=0.42354 microseconds per iteration
3=0.58949 microseconds per iteration
4=0.58363 microseconds per iteration
5=0.4351 microseconds per iteration
6=0.41378 microseconds per iteration
aotto1968
2024-12-31 18:24:30 UTC
Reply
Permalink
Post by Rich
Post by aotto1968
#!/usr/bin/env tclsh
proc test-1 { val } {
if {[regexp ^:: $val]} {
return true
} else {
return false
}
}
proc test-2 { val } {
if {[string range $val 0 1] eq "::"} {
return true
} else {
return false
}
}
set num 100000
puts 1=[time {test-1 ::otto} $num]
puts 2=[time {test-1 otto} $num]
puts 3=[time {test-2 ::otto} $num]
puts 4=[time {test-2 otto} $num]
./sbin/time-check.tcl
1=1.26311 microseconds per iteration
2=1.09152 microseconds per iteration
3=1.44028 microseconds per iteration
4=1.43917 microseconds per iteration
$ cat time-check.tcl
#!/usr/bin/env tclsh
proc test-1 { val } {
if {[regexp ^:: $val]} {
return true
} else {
return false
}
}
proc test-2 { val } {
if {[string range $val 0 1] eq "::"} {
return true
} else {
return false
}
}
proc test-3 { val } {
return [string match ::* $val]
}
set num 100000
puts 1=[time {test-1 ::otto} $num]
puts 2=[time {test-1 otto} $num]
puts 3=[time {test-2 ::otto} $num]
puts 4=[time {test-2 otto} $num]
puts 5=[time {test-3 ::otto} $num]
puts 6=[time {test-3 otto} $num]
$ ./time-check.tcl
1=0.45252 microseconds per iteration
2=0.42354 microseconds per iteration
3=0.58949 microseconds per iteration
4=0.58363 microseconds per iteration
5=0.4351 microseconds per iteration
6=0.41378 microseconds per iteration
→ thanks.
aotto1968
2024-12-31 18:33:41 UTC
Reply
Permalink
...
Post by Rich
$ cat time-check.tcl
#!/usr/bin/env tclsh
proc test-1 { val } {
if {[regexp ^:: $val]} {
return true
} else {
return false
}
}
proc test-2 { val } {
if {[string range $val 0 1] eq "::"} {
return true
} else {
return false
}
}
proc test-3 { val } {
return [string match ::* $val]
}
set num 100000
puts 1=[time {test-1 ::otto} $num]
puts 2=[time {test-1 otto} $num]
puts 3=[time {test-2 ::otto} $num]
puts 4=[time {test-2 otto} $num]
puts 5=[time {test-3 ::otto} $num]
puts 6=[time {test-3 otto} $num]
$ ./time-check.tcl
1=0.45252 microseconds per iteration
2=0.42354 microseconds per iteration
3=0.58949 microseconds per iteration
4=0.58363 microseconds per iteration
5=0.4351 microseconds per iteration
6=0.41378 microseconds per iteration
interesting

1) tcl with debug on

[debug].../NHI1> ./sbin/tcl-time-check.tcl
1=1.07665 microseconds per iteration
2=1.04722 microseconds per iteration
3=1.34974 microseconds per iteration
4=1.34743 microseconds per iteration
5=1.07671 microseconds per iteration
6=1.04552 microseconds per iteration

2) tcl with "production" switch on

[release].../NHI1> ./sbin/tcl-time-check.tcl
1=0.32721 microseconds per iteration
2=0.31452 microseconds per iteration
3=0.4352 microseconds per iteration
4=0.43953 microseconds per iteration
5=0.32741 microseconds per iteration
6=0.31617 microseconds per iteration

there is NO difference between "regexp" and "string match" for

→ Intel(R) Xeon(R) CPU E3-1275 V2 @ 3.50GHz
eric
2025-01-02 11:04:50 UTC
Reply
Permalink
....
This kind of regexp generates bytecode using string match instead.
The time difference between both is due to the if-else construct.

tcl::unsupported::disassemble proc test-1
ByteCode 0x0450C010, refCt 1, epoch 18, interp 0x0442C8C0 (epoch 18)
Source "\n if {[regexp ^:: $val]} {\n return true\n } e..."
Cmds 4, src 81, inst 36, litObjs 3, aux 0, stkDepth 2, code/src 0.00
Proc 0x04551488, refCt 1, args 1, compiled locals 1
slot 0, scalar, arg, "val"
Commands 4:
1: pc 0-34, src 4-79 2: pc 0-5, src 9-23
3: pc 9-20, src 34-44 4: pc 23-34, src 63-74
Command 1: "if {[regexp ^:: $val]} {\n return true\n } else
{..."
Command 2: "regexp ^:: $val..."
(0) push1 0 # "::*"
(2) loadScalar1 %v0 # var "val"
(4) strmatch +0
(6) nop
(7) jumpFalse1 +16 # pc 23
Command 3: "return true..."
(9) startCommand +12 1 # next cmd at pc 21, 1 cmds start here
(18) push1 1 # "true"
(20) done
(21) jump1 +14 # pc 35
Command 4: "return false..."
(23) startCommand +12 1 # next cmd at pc 35, 1 cmds start here
(32) push1 2 # "false"
(34) done
(35) done

Eric

--
aotto1968
2025-01-02 19:23:45 UTC
Reply
Permalink
Post by eric
....
This kind of regexp generates bytecode using string match instead.
The time difference between both is due to the if-else construct.
tcl::unsupported::disassemble proc test-1
ByteCode 0x0450C010, refCt 1, epoch 18, interp 0x0442C8C0 (epoch 18)
 Source "\n   if {[regexp ^:: $val]} {\n     return true\n   } e..."
 Cmds 4, src 81, inst 36, litObjs 3, aux 0, stkDepth 2, code/src 0.00
 Proc 0x04551488, refCt 1, args 1, compiled locals 1
     slot 0, scalar, arg, "val"
     1: pc 0-34, src 4-79        2: pc 0-5, src 9-23
     3: pc 9-20, src 34-44        4: pc 23-34, src 63-74
 Command 1: "if {[regexp ^:: $val]} {\n     return true\n   } else
{..."
 Command 2: "regexp ^:: $val..."
   (0) push1 0     # "::*"
   (2) loadScalar1 %v0     # var "val"
   (4) strmatch +0
   (6) nop
   (7) jumpFalse1 +16     # pc 23
 Command 3: "return true..."
   (9) startCommand +12 1     # next cmd at pc 21, 1 cmds start here
   (18) push1 1     # "true"
   (20) done
   (21) jump1 +14     # pc 35
 Command 4: "return false..."
   (23) startCommand +12 1     # next cmd at pc 35, 1 cmds start here
   (32) push1 2     # "false"
   (34) done
   (35) done
Eric
--
other stuff

# OLD

proc ::myoo::ClassIs {myR cls} {
upvar $myR my
expr {[llength [lsearch -exact -sorted [set $my(__CLASS__)::__SUPER__SORTED__] $cls]] > 0}
}

# want to have

proc ::myoo::ClassIs {myR cls} {
upvar $myR my
lsearch -exists -exact -sorted [set $my(__CLASS__)::__SUPER__SORTED__] $cls
}

ONE simple FLAG erase a lot of code.

Loading...