There seems to be a memory leak with the clock format command. I've
tested this in freewrap 6.74 on Windows and tclsh 8.6 on Linux with
the same result.
Using this code:
for { set i 0 } { $i < 1000 } { incr i } { clock format 0 -format
[expr rand()] }
There seems to be a memory leak with the clock format command. I've
tested this in freewrap 6.74 on Windows and tclsh 8.6 on Linux with
the same result.
Using this code:
for { set i 0 } { $i < 1000 } { incr i } { clock format 0 -format [expr rand()] }
I see an increase in memory of about ~2 MB. Increasing the limit from
1,000 to 10,000 yields a memory increase of ~20 MB, so it seems linear
at about 2 kB leaked per iteration. Same for 100,0000, with ~200 MB
increase.
John Jester <kuulgryphun@gmail.com> wrote:
The reason I'm dealing with this is I'm trying to make a
"clock format" that works with milli- or microseconds.
Does anyone have a recommendation for a better way to do this?
My suggestion: replace the %uS by a fixed string unlikely to
ever occur in a clock format result..., e.g. by %%uS, and then
use string map on the result (of the internal call) to replace
the %uS by the microseconds.
If you can accept a compromise for calling your custom clock format
then let users call it with %%uS (double percent), then your procedure
could pass the format string on to normal clock format directly, and
only needs to postprocess the result for %uS.
Passing it on directly should give a speed benefit, as clock
format seems to add stuff to the internal object of the format-
string, and by not recalculating it on each call, the cache
will accellerate future calls.
The reason I'm dealing with this is I'm trying to make a
"clock format" that works with milli- or microseconds.
Does anyone have a recommendation for a better way to do this?
On
https://wiki.tcl-lang.org/page/Add+a+time+stamp+to+each+line+of+output
I'm using %n for milliseconds and %v for microseconds.
I guess that code could benefit from the insights gained here. In other words, do the clock format first and mapping %n and %v later. That is possible because the clock command leaves format groups it doesn't know alone. The advantage of doing the mapping first was that it would still
work if those format groups would be added to the clock command in the future.
On 18/05/2023 11:36, Andreas Leitgeb wrote:
John Jester <kuulgryphun@gmail.com> wrote:On
The reason I'm dealing with this is I'm trying to make aMy suggestion: replace the %uS by a fixed string unlikely to
"clock format" that works with milli- or microseconds.
Does anyone have a recommendation for a better way to do this?
ever occur in a clock format result..., e.g. by %%uS, and then
use string map on the result (of the internal call) to replace
the %uS by the microseconds.
If you can accept a compromise for calling your custom clock format
then let users call it with %%uS (double percent), then your procedure
could pass the format string on to normal clock format directly, and
only needs to postprocess the result for %uS.
Passing it on directly should give a speed benefit, as clock
format seems to add stuff to the internal object of the format-
string, and by not recalculating it on each call, the cache
will accellerate future calls.
https://wiki.tcl-lang.org/page/Add+a+time+stamp+to+each+line+of+output
I'm using %n for milliseconds and %v for microseconds.
I guess that code could benefit from the insights gained here. In other words, do the clock format first and mapping %n and %v later. That is possible because the clock command leaves format groups it doesn't know alone. The advantage of doing the mapping first was that it would still
work if those format groups would be added to the clock command in the future.
My suggestion: replace the %uS by a fixed string unlikely to
ever occur in a clock format result..., e.g. by %%uS, and then
use string map on the result (of the internal call) to replace
the %uS by the microseconds.
On 2023-05-18, Andreas Leitgeb wrote:
John Jester <kuulgryphun@gmail.com> wrote:
The reason I'm dealing with this is I'm trying to make a
"clock format" that works with milli- or microseconds.
Does anyone have a recommendation for a better way to do this?
My suggestion: replace the %uS by a fixed string unlikely to
ever occur in a clock format result..., e.g. by %%uS, and then
use string map on the result (of the internal call) to replace
the %uS by the microseconds.
On Thursday, May 18, 2023 at 2:36:36 AM UTC-7, Andreas Leitgeb wrote:
My suggestion: replace the %uS by a fixed string unlikely to
ever occur in a clock format result..., e.g. by %%uS, and then
use string map on the result (of the internal call) to replace
the %uS by the microseconds.
This has worked beautifully, thank you!
[...]
Thanks all, problem solved on my end. Though Tcl still has the memory leak...
John Jester <kuulgryphun@gmail.com> writes:
On Thursday, May 18, 2023 at 2:36:36â¯AM UTC-7, Andreas Leitgeb wrote:
My suggestion: replace the %uS by a fixed string unlikely to
ever occur in a clock format result..., e.g. by %%uS, and then
use string map on the result (of the internal call) to replace
the %uS by the microseconds.
This has worked beautifully, thank you!
[...]
Thanks all, problem solved on my end. Though Tcl still has the memory leak...
Fine that you have found a working solution for you problem.
As already suspected in my prior analysis this is not a memory leak in a strong sense. It's a deliberate detail of the implementation. See this comment:
https://core.tcl-lang.org/tcl/file?udc=1&ln=1455-1482&ci=b1fc8161f1f67f28&name=library%2Fclock.tcl
and study the proc implementation for how it is done. In short for every -format and -locale combination an own parsing procedure is created (and
such scan procedures are not deleted once installed).
This script shows this:
proc doit {nr} {
for { set i 0 } { $i < $nr } { incr i } {
clock format 0 -format $i
}
}
# Populate the ::tcl::clock namespace with a first call
clock format 0
puts "Procs in the namespace ::tcl::clock [llength [info proc ::tcl::clock::*]]"
doit 1000
puts "Procs in the namespace ::tcl::clock [llength [info proc ::tcl::clock::*]]"
Procs in the namespace ::tcl::clock 52
Procs in the namespace ::tcl::clock 1052
Now, if that should stay this way or if that could or should be
implemented in another way without that side effect or if a knob or flag should be added for use cases like you had is another question.
rolf
On Thursday, May 18, 2023 at 2:36:36 AM UTC-7, Andreas Leitgeb wrote:
My suggestion: replace the %uS by a fixed string unlikely toThis has worked beautifully, thank you!
ever occur in a clock format result..., e.g. by %%uS, and then
use string map on the result (of the internal call) to replace
the %uS by the microseconds.
I allow the user to pass %us or %ms to my wrapper, which pre-processes
with a string map to replace them with %%us or %%ms, then calls real
clock which reverts them back to %us and %ms (as well as doing the
whole format), then the wrapper post-processes the result with another
string map to replace %us or %ms with the value for micro- or
milliseconds.
All with no memory leak since clock format is always
passed the same format string.
At Thu, 18 May 2023 17:03:55 +0200 Rolf Ade <rolf@pointsman.de> wrote:
As already suspected in my prior analysis this is not a memory leak in a
strong sense. It's a deliberate detail of the implementation. See this
comment:
https://core.tcl-lang.org/tcl/file?udc=1&ln=1455-1482&ci=b1fc8161f1f67f28&name=library%2Fclock.tcl
[...]
Now, if that should stay this way or if that could or should be
implemented in another way without that side effect or if a knob or flag
should be added for use cases like you had is another question.
So I guess if one is computing a one-time format for clock format (eg [clock format ... -format $x]), then one needs to do a rename of ::tcl::clock::formatproc'$x'c to the empty string:
proc clockformatonetime {time fmt} {
set result [clock format $time -format $fmt]
rename ::tcl::clock::formatproc'$fmt'c {}
return $result
}
This should free up the space (or really recycle it).
Maybe at least a -once flag ...
Rolf Ade <rolf@pointsman.de> wrote:
Maybe at least a -once flag ...
or "-nocache" ... But I'm not going to TIP it.
There seems to be a memory leak with the clock format command. I've tested this in freewrap 6.74 on Windows and tclsh 8.6 on Linux with the same result.
Using this code:
for { set i 0 } { $i < 1000 } { incr i } { clock format 0 -format [expr rand()] }
I see an increase in memory of about ~2 MB. Increasing the limit from 1,000 to 10,000 yields a memory increase of ~20 MB, so it seems linear at about 2 kB leaked per iteration. Same for 100,0000, with ~200 MB increase.
The reason I discovered this is I was trying to extend "clock format" to work with milli- and microseconds, so I was doing something like this:
clock format [clock microseconds] -format {%H:%M:%S.%us}
clock format <seconds from above> -format {%H:%M:%S.123456}
which is how I ended up asking clock format to do a bunch of different formats in rapid succession.
Am 17.05.2023 um 23:30 schrieb John Jester:With all the tct changes underway we should try to convince sebres to join again.
There seems to be a memory leak with the clock format command. I've tested this in freewrap 6.74 on Windows and tclsh 8.6 on Linux with the same result.
Using this code:
for { set i 0 } { $i < 1000 } { incr i } { clock format 0 -format [expr rand()] }
I see an increase in memory of about ~2 MB. Increasing the limit from 1,000 to 10,000 yields a memory increase of ~20 MB, so it seems linear at about 2 kB leaked per iteration. Same for 100,0000, with ~200 MB increase.
The reason I discovered this is I was trying to extend "clock format" to work with milli- and microseconds, so I was doing something like this:
clock format [clock microseconds] -format {%H:%M:%S.%us}
clock format <seconds from above> -format {%H:%M:%S.123456}
which is how I ended up asking clock format to do a bunch of different formats in rapid succession.John,
if you want to look in speed-up of the clock command, magic Sergey
Brester, has made a speed-up of factor 20 implementation.
It is in the TCL branch https://core.tcl-lang.org/tcl/timeline?r=sebres-8-7-clock-speedup-cr2
It would be great, if this gem could be considered and merged one day. Unfortunately, the work of Sergey is so high level, that nobody eles understands it. There are a couple of propositions by him in core
branches, all starting with "sebres" (his login).
Take care,
Harald
Sysop: | Keyop |
---|---|
Location: | Huddersfield, West Yorkshire, UK |
Users: | 497 |
Nodes: | 16 (2 / 14) |
Uptime: | 07:07:05 |
Calls: | 9,780 |
Calls today: | 21 |
Files: | 13,748 |
D/L today: |
1 files (1K bytes) |
Messages: | 6,186,854 |