1# Trying to find out how hash performance degrades as size increases
2
3if [catch {package require Mk4tcl}] {
4  catch {load ./Mk4tcl[info sharedlibext] mk4tcl}
5  catch {load ./Mk4tcl_d.dll mk4tcl}
6}
7
8proc loadwords {step} {
9  global warray
10  set fd [open /usr/share/dict/words]
11  #set fd [open words]
12  for {set i 0} {$i < $step && [gets $fd line] >= 0} {incr i} {
13    set warray($line) $i
14  }
15  close $fd
16  return $line
17}
18
19proc timedRun {tag count args} {
20  set usec [lindex [time $args $count] 0]
21  lappend ::stats($tag) [expr {$count*$usec/1000.0}]
22}
23
24proc setup {keys type} {
25  file delete _large.mk
26  mk::file open db _large.mk -nocommit
27
28  set layout "$keys v"
29  if {$type == "b"} { set layout "{_B {$layout}}" }
30  mk::view layout db.words $layout
31
32  if {$type == "b"} {
33    mk::view open db.words rawdata
34    rename [rawdata view blocked] data
35  } else {
36    mk::view open db.words data
37  }
38
39  mk::view layout db.words_map {_H:I _R:I}
40  mk::view open db.words_map map
41
42  rename [data view hash map [regsub -all k $keys {} x]] words
43}
44
45proc teardown {} {
46  catch { rename words "" }
47  catch { rename data "" }
48  catch { rename map "" }
49  catch { rename rawdata "" }
50
51  mk::file close db
52}
53
54proc fill1 {seq} {
55  global warray
56  foreach {k v} [array get warray] {
57    set x $k$seq
58    words insert end k1 k1_$x v v_$x
59  }
60}
61
62proc fill2 {seq} {
63  global warray
64  foreach {k v} [array get warray] {
65    set x $k$seq
66    words insert end k1 k1_$x k2 k2_$x
67  }
68}
69
70proc fill5 {seq} {
71  global warray
72  foreach {k v} [array get warray] {
73    set x $k$seq
74    words insert end k1 k1_$x k2 k2_$x v1 v1_$x v2 v2_$x v3 v3_$x v v_$x
75  }
76}
77
78proc find1 {w} {
79  words find k1 k1_${w}5
80}
81
82proc find2 {w} {
83  words find k1 k1_${w}5 k2 k2_${w}5
84}
85
86proc find5 {w} {
87  words find k1 k1_${w}5 k2 k2_${w}5
88}
89
90set step 10000
91#set step 100
92set mult 50
93
94set w [loadwords $step]
95puts "w = $w"
96puts [clock format [clock seconds]]
97
98foreach type {f b} {
99  foreach keys {{k1} {k1 k2} {k1 k2 v1 v2 v3}} {
100    set nkeys [llength $keys]
101    set mode "$type$nkeys"
102    puts -nonewline stderr "$mode: "
103    setup $keys $type
104    for {set i 0} {$i < $mult} {incr i} {
105      timedRun $mode-fill 1 fill$nkeys $i
106      puts -nonewline stderr .
107    }
108    timedRun $mode-find 10000 find$nkeys $w
109    timedRun $mode-commit 1 mk::file commit db
110    puts stderr "  [words size] rows, [file size _large.mk] b"
111    for {set i 0} {$i < 3} {incr i} {
112      puts " $i: [words get $i]"
113    }
114    teardown
115  }
116}
117
118puts [clock format [clock seconds]]
119
120puts -nonewline "\n               "
121foreach x [lsort [array names stats *-fill]] {
122  puts -nonewline [format %8s [lindex [split $x -] 0]]
123  set i 0
124  foreach y $stats($x) {
125    incr i $step
126    append cols([format %6d $i]) [format {%8.2f} $y]
127  }
128  unset stats($x)
129}
130puts \n
131parray cols
132puts ""
133parray stats
134puts ""
135puts [clock format [clock seconds]]
136