Posted to tcl by hypnotoad at Thu May 11 12:19:25 GMT 2017view raw

  1. proc foreach* {args} {
  2. set script [lindex $args end]
  3. set args [lrange $args 0 end-1]
  4. set dictval [concat {*}[lmap {k _} $args {string cat "[list $k] \[set [list $k]\]"}]]
  5. set script "set values \[dict create $dictval\]\n $script"
  6. foreach {b a} [lreverse $args] {
  7. set script [list foreach $a $b $script]
  8. }
  9. tailcall {*}$script
  10. }
  11.  
  12. proc permutation_level {combinations body valuevar values level} {
  13. incr level
  14. foreach {field valuelist} $combinations {
  15. if {[dict exists $values $field]} continue
  16. if {[llength $valuelist]==0} {
  17. dict set values $field {}
  18. permutation_level $combinations $body $valuevar $values $level
  19. } else {
  20. foreach value $valuelist {
  21. dict set values $field $value
  22. permutation_level $combinations $body $valuevar $values $level
  23. }
  24. }
  25. return
  26. }
  27. upvar $level $valuevar _thevals
  28. set _thevals $values
  29. uplevel $level $body
  30. }
  31. proc permutation {combinations body {valuevar values}} {
  32. set body [list dict with $valuevar $body]
  33. permutation_level $combinations $body $valuevar {} 1
  34. }
  35.  
  36.  
  37.  
  38. proc benchmark DATASET {
  39. # Shimmer DATASET to be a list
  40. llength $DATASET
  41.  
  42. set trial 0
  43. set start [clock clicks]
  44. foreach* {*}$DATASET {
  45. set foreach*_clicks([incr trial]) [expr {[clock clicks]-$start}]
  46. }
  47. set end [clock clicks]
  48. puts [list foreach* [expr {$trial+1}] entries total time: [expr {$end-$start}] first: ${foreach*_clicks(1)}]
  49. #parray foreach*_clicks
  50.  
  51. set trial 0
  52. set start [clock clicks]
  53. permutation $DATASET {
  54. set permutation_clicks([incr trial]) [expr {[clock clicks]-$start}]
  55. }
  56. set end [clock clicks]
  57. puts [list permutation [expr {$trial+1}] entries total time: [expr {$end-$start}] first: $permutation_clicks(1)]
  58. #parray permutation_clicks
  59.  
  60. }
  61.  
  62. puts "Small Dataset"
  63. set DATASET {
  64. compartment {5compt}
  65. generator {one two three}
  66. switchboard {one two three}
  67. }
  68.  
  69. benchmark $DATASET
  70.  
  71. puts "Larger Dataset"
  72. set DATASET {
  73. compartment {5compt 8compt}
  74. generator {one two three}
  75. switchboard {one two three}
  76. cwplant {single double}
  77. cwloop {single portstarb foraft psfa}
  78. }
  79.  
  80. benchmark $DATASET
  81.  
  82. puts "Huge Dataset"
  83. set DATASET {
  84. compartment {5compt 8compt 16compt cruiser}
  85. generator {one two three four}
  86. switchboard {one two three}
  87. cwplant {single double triple quad}
  88. cwloop {single portstarb foraft psfa}
  89. propulsion {diesel gtm hybrid}
  90. helocopter {none mh60 mh60+uav 2mh60 2uav}
  91. dc_locker {one two three four}
  92. }
  93. benchmark $DATASET
  94.  
  95. # Results:
  96. #Small Dataset
  97. #foreach* 10 entries total time: 103 first: 84
  98. #permutation 10 entries total time: 120 first: 80
  99. #Larger Dataset
  100. #foreach* 145 entries total time: 315 first: 43
  101. #permutation 145 entries total time: 871 first: 20
  102. #Huge Dataset
  103. #foreach* 46081 entries total time: 109106 first: 56
  104. #permutation 46081 entries total time: 266426 first: 39
  105. ###