Sometimes, if you have large arrays, it is better to not use '''[foreach]''' and '''[array] get''' to loop through an array, as it creates a list copy of your array with a quite hefty memory cost: foreach {key value} [array get arrName] {#do something with key and value} Another alternative is foreach key [array names arrName] { #get current value with $arrName($key) } foreach key [lsort -dictionary [array names foo]] { ... } Better do it like this, using '''[while]''' and the '''[array]''' search facilities. (Those are a direct mapping of the C level functionality for a Tcl_HashTable ). set searchToken [array startsearch largeArray] while {[array anymore largeArray $searchToken]} { set key [array nextelement largeArray $searchToken] set value $largeArray($key) # do something with key/value } array donesearch largeArray $searchToken Question: how big does an array need to be to make this the better approach? [KBK] - As a guideline, [[array names]] and [[array get]] will allocate: * a C array of up to 2N (for [[array names]]) or 4N (for [[array get]]) Tcl_Obj pointers, where N is the size of the Tcl array. * N Tcl_Obj's to hold the array keys. * A copy of the string representation of each of the array keys. This overhead can be substantial if the array already nearly fills memory. Using ''startsearch'', ''anymore'', ''nextelement'' and ''donesearch'' allocates only a constant amount of memory (plus the size of the largest key). On the other hand, it's atrociously slow, because it executes so much Tcl code, and because it has to revalidate the search handle on every call. [[array get]] and [[array names]] are much, much faster because they copy the data - and don't need to worry about someone changing the array while they're executing. (If you know why this statement is an oversimplification, you don't need to read this discussion!) So, I think that resorting to the element-at-a-time array iteration is a desperate move, to be resorted to only when the application will consume excessive memory without it. For day-to-day array operations, [[array get]] is both clearer and faster. One-line summary: "When is [[array startsearch]] the better approach?" "Almost never, unless the array is so huge that a second copy would crash the program or thrash the virtual memory." ---- I think often what people are looking for when searching an array for specific keys can be done using ''array get'' with a wildcard. Example: foreach {key value} [array get ::largeArray customer*] { #do something foreach customer } ---- Q: ''"When is [[array startsearch]] the better approach?" ...'' A: When you have a huge array where each element must be visited. Memory wasn't so much the issue as building and passing a list of array names. I have an array (arr) of 500,000 iTcl objects and must invoke a method on each: time {foreach n [array names arr] {$arr($n) dosomething}} 5 2602631 microseconds per iteration Now, consider this adhoc foreach_name proc (it's a hack and can be improved): proc foreach_name {key array cmd} { set id [uplevel "array startsearch $array"] uplevel "while {\[set $key \[array nextelement $array $id]] != {}} { $cmd }" uplevel "array donesearch $array $id" } time {foreach_name n arr {$arr($n) dosomething}} 5 1896987 microseconds per iteration As implemented in Tcl 8.4, on a Pentium 4 under Windows 2000. -- [Todd Coram] This looks a bit like unequal starting conditions. The first example uses proc, the second does not. Did you time the difference if you put the foreach loop into a proc? --