Question about TCL speed

67 views
Skip to first unread message

aotto1968

unread,
Jun 22, 2022, 1:48:43 PMJun 22
to

Hi,

this is a piece of code to delete a *const* prefix (librx) from a string
(str)

OLD:

proc pCleanLibRx { str } {
regsub "${::librx}(\\w+)$" $str {\1}
}

as you see the string is *not* static by definition only by *logic*

Question it is efficient to keep the code as it is **OR** to add a
global variable with a *non-changing* global value

NEW

set myRX "${::librx}(\\w+)$"

proc pCleanLibRx { str } {
regsub $::myRX $str {\1}
}

If second is faster than TCL has an open point to add a CONST on-time
define to a inline string.

possible NEW:

proc pCleanLibRx { str } {
regsub [CONST ${::librx}(\\w+)$"] $str {\1}
}

CONST = make a hint to the tcl that the string is CONST
→ the value can be cached


mfg

Christian Gollwitzer

unread,
Jun 22, 2022, 4:10:25 PMJun 22
to
Am 22.06.22 um 18:48 schrieb aotto1968:
>
> Hi,
>
> this is a piece of code to delete a *const* prefix (librx) from a string
> (str)
>
> OLD:
>
> proc pCleanLibRx { str } {
>   regsub "${::librx}(\\w+)$" $str {\1}
> }
>
> as you see the string is *not* static by definition only by *logic*


Instead of asking, which one is faster, you should benchmark it. There
is the time command in the core (and, in newer cores, also the timerate
command)


> Question it is efficient to keep the code as it is **OR** to add a
> global variable with a *non-changing* global value
>
> NEW
>
> set myRX "${::librx}(\\w+)$"

I would expect that there is no big difference. The largest effort is
put into compiling the RE into its internal representation. For both
code paths, this is done only once at the first regexp invocation. The
literal string in the proc is stored in a literal table, i.e. what you
propose to do, is already done by the byte code compiler AFAIUI.

Christian

Christian Gollwitzer

unread,
Jun 22, 2022, 4:14:28 PMJun 22
to
...sorry, that was a bit too fast;
Am 22.06.22 um 21:10 schrieb Christian Gollwitzer:
> Am 22.06.22 um 18:48 schrieb aotto1968:
>>

> Instead of asking, which one is faster, you should benchmark it. There
> is the time command in the core (and, in newer cores, also the timerate
> command)

This still holds: Time it
>
>
>> Question it is efficient to keep the code as it is **OR** to add a
>> global variable with a *non-changing* global value
>>
>> NEW
>>
>> set myRX "${::librx}(\\w+)$"
>
> I would expect that there is no big difference. The largest effort is

Indeed, for a dynamic string like this, the global variable should be
faster. Still, the RE engine caches not only the conmpiled expressino in
the intrep, but also the most recently used expression strings in order
to deal with this problem of dynamically constructed const strings. That
is special to regexp and does not hold for any other shimmering issue.

Christian

aotto1968

unread,
Jun 22, 2022, 4:40:37 PMJun 22
to

>>
>>> Question it is efficient to keep the code as it is **OR** to add a
>>> global variable with a *non-changing* global value
>>>
>>> NEW
>>>
>>> set myRX "${::librx}(\\w+)$"
>>
>> I would expect that there is no big difference. The largest effort is
>
> Indeed, for a dynamic string like this, the global variable should be
> faster. Still, the RE engine caches not only the conmpiled expressino in
> the intrep, but also the most recently used expression strings in order
> to deal with this problem of dynamically constructed const strings. That
> is special to regexp and does not hold for any other shimmering issue.
>
>     Christian

thanks for the answer… I thing a lot of performance is lost in tcl
because of the *const-by-logic* issue.

It is a typical task to define some *const* values at the beginning and
use this *const* to do any kind of 'workload' like the one above.

probably a better solution would be to define the object at all ans
const and in the code at any place a usage sonst will be const as well.

in our case

"${::librx}(\\w+)$" is a concat of "${::librx}" and "(\\w+)$" both are
*const* and the result will be *const* too.

mfg

Gerald Lester

unread,
Jun 22, 2022, 5:25:01 PMJun 22
to
On 6/22/22 15:40, aotto1968 wrote:
>
>>>
>>>> Question it is efficient to keep the code as it is **OR** to add a
>>>> global variable with a *non-changing* global value
>>>>
>>>> NEW
>>>>
>>>> set myRX "${::librx}(\\w+)$"
>>>
>>> I would expect that there is no big difference. The largest effort is
>>
>> Indeed, for a dynamic string like this, the global variable should be
>> faster. Still, the RE engine caches not only the conmpiled expressino
>> in the intrep, but also the most recently used expression strings in
>> order to deal with this problem of dynamically constructed const
>> strings. That is special to regexp and does not hold for any other
>> shimmering issue.
>>
>> Christian
>
> thanks for the answer… I think a lot of performance is lost in tcl
> because of the *const-by-logic* issue.
>...

Don't think/guess -- test using the timing commands!!!!


--
+----------------------------------------------------------------------+
| Gerald W. Lester, President, KNG Consulting LLC |
| Email: Gerald...@kng-consulting.net |
+----------------------------------------------------------------------+

heinrichmartin

unread,
Jun 23, 2022, 2:28:57 AMJun 23
to
On Wednesday, June 22, 2022 at 7:48:43 PM UTC+2, aotto1 wrote:
> this is a piece of code to delete a *const* prefix (librx) from a string
> (str)
>
> OLD:
>
> proc pCleanLibRx { str } {
> regsub "${::librx}(\\w+)$" $str {\1}
> }

Besides, the RE is not as intended. You could also test with [regsub "^${::librx}" $str ""]. Note the anchor at the beginning of the string. And not matching the full string might or might not be valid in your use case (i.e. only remove the prefix for special strings?).

Also, have you looked at ::textutil::trimPrefix [1]?

[1] https://core.tcl-lang.org/tcllib/doc/trunk/embedded/md/tcllib/files/modules/textutil/textutil.md#14
Reply all
Reply to author
Forward
0 new messages