## SetOps, Difference, Timing Script

# -*- tcl -*-

``` # test = diff

set max 50

proc testA {a b} {
if {[llength \$a] == 0} {
return {}
}
if {[llength \$b] == 0} {
return \$a
}

set res {}

set a [lsort \$a]
set b [lsort \$b]

while {1} {
# Store lindex/0,1 in var, access later faster ?
set n [string compare [lindex \$a 0] [lindex \$b 0]]
if {\$n == 0} {
# A = B => element in both, so not in difference
set a [lrange \$a 1 end]
set b [lrange \$b 1 end]
} elseif {\$n > 0} {
# A > B, remove B, we are beyond the element.
set b [lrange \$b 1 end]
} else {
# A < B, remove A, we are beyond the element.
# This element in A is part of the result too.
lappend res [lindex \$a 0]
set a [lrange \$a 1 end]
}
if {[llength \$a] == 0} {
return \$res
}
if {[llength \$b] == 0} {
foreach e \$a {
lappend res \$a
}

return \$res
}
}

return \$res
}

proc testB {a b} {
if {[llength \$a] == 0} {
return {}
}
if {[llength \$b] == 0} {
return \$a
}

set res {}

foreach e \$b {
set ba(\$e) .
}

foreach e \$a {
if {![info exists ba(\$e)]} {
lappend res \$e
}
}

return \$res
}

proc testC {a b} {
if {[llength \$a] == 0} {
return {}
}
if {[llength \$b] == 0} {
return \$a
}

set res {}

foreach \$b {.} {break}

foreach e \$a {
if {![info exists \$e]} {
lappend res \$e
}
}

return \$res
}

# DF_NE -> a, b   random, unsorted, intersection almost always empty
# DF_EQ -> a = b, random

set fa1  [open "|./2nep DF_A_NE Ar.dat   X.dat" w]
set fa2  [open "|./2nep DF_A_EQ Ae0.dat  X.dat" w]

set fb1  [open "|./2nep DF_B_NE Br.dat   X.dat" w]
set fb2  [open "|./2nep DF_B_EQ Be0.dat  X.dat" w]

set fc1  [open "|./2nep DF_C_NE Cr.dat   X.dat" w]
set fc2  [open "|./2nep DF_C_EQ Ce0.dat  X.dat" w]

set fx   [open "|./2nep DF_X     X.dat" w]

set a0 {}
set b0 {}

puts stdout " ______________________________" ; flush stdout
puts stdout " DIFF | ......A ......B ......C" ; flush stdout

for {set i 0} {\$i <= \$max} {incr i} {
set ix [format %03d \$i]

puts stderr "   * \$ix (a0) =  \$a0" ; flush stderr
puts stderr "   * \$ix (b0) =  \$b0" ; flush stderr

set ra1  [lindex [time {testA \$a0 \$b0} 1000] 0]
set ra2  [lindex [time {testA \$a0 \$a0} 1000] 0]

set rb1  [lindex [time {testB \$a0 \$b0} 1000] 0]
set rb2  [lindex [time {testB \$a0 \$a0} 1000] 0]

set rc1  [lindex [time {testC \$a0 \$b0} 1000] 0]
set rc2  [lindex [time {testC \$a0 \$a0} 1000] 0]

puts stdout " ______________________________" ; flush stdout
puts stdout " \$ix NE [format %7d \$ra1] [format %7d \$rb1] [format %7d \$rc1]"
puts stdout " \$ix EQ [format %7d \$ra2] [format %7d \$rb2] [format %7d \$rc2]"

puts \$fa1 \$ra1
puts \$fa2 \$ra2

puts \$fb1 \$rb1
puts \$fb2 \$rb2

puts \$fc1 \$rc1
puts \$fc2 \$rc2

puts \$fx  \$i

lappend a0 [string range [lindex [split [expr {rand()}] .] 1] 0 4]
lappend b0 [string range [lindex [split [expr {rand()}] .] 1] 0 4]
}

puts stderr "----"     ; flush stderr
puts stdout " ______________________________" ; flush stdout

close \$fa1
close \$fa2

close \$fb1
close \$fb2

close \$fc1
close \$fc2

close \$fx```