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