is_empty returns true if
$string is the
empty string.
It is efficient even if
$string is large binary data (see test output below).
It would be nice if there was an optimisation in the interpreter for
... eq {} or
string equal to make this unnecessary.
proc is_empty {string} {
expr {![binary scan $string c c]}
}
proc not_empty {string} {
expr {![is_empty $string]}
}
Update: it seems that
string length $data is even faster. I guess there is a recent optimisation in
string length that avoids translating the binary to a string. See output below...
Test:
foreach cmd {
{expr {$data == {}}}
{expr {$data eq {}}}
{string bytelength $data}
{string equal $data {}}
{string length $data}
{is_empty $data}
} {
set data [file get ~/stuff/file.dat]
puts "$cmd\n [time {set r [eval $cmd]}]\n result = $r\n"
unset data
puts ""
}
Output:
expr {$data == {}}
1099855 microseconds per iteration
result = 0
expr {$data eq {}}
1094751 microseconds per iteration
result = 0
string bytelength $data
1076724 microseconds per iteration
result = 378629364
string equal $data {}
1078098 microseconds per iteration
result = 0
string length $data
22 microseconds per iteration
result = 191470592
is_empty $data
42 microseconds per iteration
result = 0
bll 2016-10-23 Timing a single iteration is not useful. The data below is for 100000 iterations. I also modified a couple of the tests to match the expected test result.
expr {$data == {}}
1.08223 microseconds per iteration
result = 0
expr {$data eq {}}
0.7982 microseconds per iteration
result = 0
expr [string bytelength $data] == 0
2.95837 microseconds per iteration
result = 0
expr ! [string bytelength $data]
2.52733 microseconds per iteration
result = 0
string equal $data {}
0.78472 microseconds per iteration
result = 0
expr [string length $data] == 0
2.71773 microseconds per iteration
result = 0
expr ! [string length $data]
2.38082 microseconds per iteration
result = 0
is_empty $data
1.79519 microseconds per iteration
result = 0