Hashes, Part II Back to the Win32 Shootout
Back to dada's perl lab

[The Original Shootout]   [NEWS]   [FAQ]   [Methodology]   [Platform Details]   [Acknowledgements]   [Scorecard]  
All Source For Hashes, Part II
hash2.awka
# $Id: hash2.gawk,v 1.2 2001/05/20 06:13:00 doug Exp $
# http://www.bagley.org/~doug/shootout/

BEGIN {
    n = (ARGV[1] < 1) ? 1 : ARGV[1];

    for (i=0; i<10000; i++)
    hash1[sprintf("foo_%d", i)] = i
    for (i=0; i<n; i++)
    for (k in hash1)
        hash2[k] += hash1[k]
    print hash1["foo_1"], hash1["foo_9999"], hash2["foo_1"], hash2["foo_9999"]
}
hash2.bcc
/* -*- mode: c -*-
 * $Id: hash2.gcc,v 1.3 2001/01/07 16:23:00 doug Exp $
 * http://www.bagley.org/~doug/shootout/
 */

#include <stdio.h>
#include <stdlib.h>
#define inline
#include "simple_hash.h"

int main(int argc, char *argv[]) {
    int i, n = ((argc == 2) ? atoi(argv[1]) : 1);
    char buf[32];
    struct ht_ht *ht1 = ht_create(10000);
    struct ht_ht *ht2 = ht_create(10000);
    struct ht_node *node;

    for (i=0; i<=9999; ++i) {
    sprintf(buf, "foo_%d", i);
    ht_find_new(ht1, buf)->val = i;
    }

    for (i=0; i<n; ++i) {
    for (node=ht_first(ht1); node; node=ht_next(ht1)) {
        ht_find_new(ht2, node->key)->val += node->val;
    }
    }

    printf("%d %d %d %d\n",
       (ht_find(ht1, "foo_1"))->val,
       (ht_find(ht1, "foo_9999"))->val,
       (ht_find(ht2, "foo_1"))->val,
       (ht_find(ht2, "foo_9999"))->val);

    ht_destroy(ht1);
    ht_destroy(ht2);
    return(0);
}
hash2.csharp
// $Id: hash2.csharp,v 1.0 2002/02/14 15:01:00 dada Exp $
// http://dada.perl.it/shootout/

using System;
using System.Collections;

class App {
    public static int Main(String[] args) {        
        int n;        
        Hashtable hash1 = new Hashtable();
        Hashtable hash2 = new Hashtable();
        
        n = System.Convert.ToInt32(args[0]);
        if(n < 1) n = 1;
                
        for(int i=0; i<=9999; i++) {
            hash1.Add( "foo_" + i.ToString(), i);
        }
        
        for(int i = 0; i < n; i++) {
            IDictionaryEnumerator it = hash1.GetEnumerator();
            while(it.MoveNext()) {
                if(hash2.ContainsKey(it.Key)) {
                    int v1 = (int) hash1[it.Key];
                    int v2 = (int) hash2[it.Key];                
                    hash2[it.Key] = v1 + v2;
                } else {
                    hash2.Add(it.Key, hash1[it.Key]);
                }
            }
        }
        Console.WriteLine(hash1["foo_1"] + " " + hash1["foo_9999"] + " " + hash2["foo_1"] + " " + hash2["foo_9999"]);
        return(0);
    }
}
hash2.cygperl
#!/usr/local/bin/perl
# $Id: hash2.perl,v 1.3 2001/01/18 23:38:26 doug Exp $
# http://www.bagley.org/~doug/shootout/
# with help from Steve Fink

use strict;

my $n = ($ARGV[0] > 0) ? $ARGV[0] : 1;
my %hash1 = ();
$hash1{"foo_$_"} = $_ for 0..9999;
my %hash2 = ();
my($k, $v);
for (1..$n) {
    $hash2{$_} += $hash1{$_} while (defined ($_ = each %hash1));
}
print "$hash1{foo_1} $hash1{foo_9999} $hash2{foo_1} $hash2{foo_9999}\n";
hash2.delphi
program hash2_2;



uses
  simpleHash in 'simpleHash.pas';

var h1,h2: TStringHash;
    p1,p2: PHashEntry;
    n, i: cardinal;
    code: integer;
    s: string;
begin
  n :=1;
  if ParamCount=1 then
    Val(ParamStr(1),n,code);

  h1:=TStringHash.Create;
  for i:=1 to 10000 do begin
    str(i, s);
    h1.add('foo_'+s,i);
  end;

  h2:=TStringHash.Create;
  for i:=1 to n do begin
    p1:=h1.getFirst;
    while p1<>nil do begin
      p2:=h2.get(p1^.Key);
      if p2=nil then
        h2.add(p1^.Key,p1^.Value)
      else
        inc(p2^.Value,p1^.Value);
      p1:=h1.getNext;
    end;
  end;
  writeLn(h1.get('foo_1')^.Value,' ',
          h1.get('foo_9999')^.Value,' ',
          h2.get('foo_1')^.Value,' ',
          h2.get('foo_9999')^.Value);
  h1.Destroy;
  h2.Destroy;
end.

hash2.erlang
%%% -*- mode: erlang -*-
%%% $Id: hash2.erlang,v 1.1 2001/05/21 02:22:57 doug Exp $
%%% http://www.bagley.org/~doug/shootout/

%% Use ETS tables (Erlang's associative store).

-module(hash2).
-export([main/0, main/1]).

main() -> main(['1']).
main([Arg]) ->
    N = list_to_integer(atom_to_list(Arg)),
    H1 = ets:new(one, [set]),
    H2 = ets:new(two, [set]),
    doinserts1(0, H1),
    doinserts2(N, H1, H2),
    io:format("~w ~w ~w ~w~n", [value(H1, list_to_atom("foo_1")),
                value(H1, list_to_atom("foo_9999")),
                value(H2, list_to_atom("foo_1")),
                value(H2, list_to_atom("foo_9999"))]),
    halt(0).

doinserts1(10000, _) -> ok;
doinserts1(I, H) ->
    Key = list_to_atom(lists:append("foo_", integer_to_list(I))),
    ets:insert(H, { Key, I }),
    doinserts1(I+1, H).

doinserts2(0, _, _) -> ok;
doinserts2(I, H1, H2) ->
    addTables(H1, H2),
    doinserts2(I-1, H1, H2).

addTables(H1, H2) ->
    Key = ets:first(H1),
    addTables(Key, H1, H2).

value(Tab, Key) -> { _, V } = hd(ets:lookup(Tab, Key)), V.

addTables('$end_of_table', _, _) -> ok;
addTables(Key, H1, H2) ->
    Val1 = value(H1, Key),
    case (catch ets:update_counter(H2, Key, Val1)) of
    {'EXIT', {badarg, _}} -> ets:insert(H2, {Key, Val1});
    _                     -> true
    end,
    addTables(ets:next(H1, Key), H1, H2).

hash2.gawk
# $Id: hash2.gawk,v 1.2 2001/05/20 06:13:00 doug Exp $
# http://www.bagley.org/~doug/shootout/

BEGIN {
    n = (ARGV[1] < 1) ? 1 : ARGV[1];

    for (i=0; i<10000; i++)
    hash1[sprintf("foo_%d", i)] = i
    for (i=0; i<n; i++)
    for (k in hash1)
        hash2[k] += hash1[k]
    print hash1["foo_1"], hash1["foo_9999"], hash2["foo_1"], hash2["foo_9999"]
}
hash2.gcc
/* -*- mode: c -*-
 * $Id: hash2.gcc,v 1.3 2001/01/07 16:23:00 doug Exp $
 * http://www.bagley.org/~doug/shootout/
 */

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include "simple_hash.h"

int main(int argc, char *argv[]) {
    int i, n = ((argc == 2) ? atoi(argv[1]) : 1);
    char buf[32];
    struct ht_ht *ht1 = ht_create(10000);
    struct ht_ht *ht2 = ht_create(10000);
    struct ht_node *node;

    for (i=0; i<=9999; ++i) {
    sprintf(buf, "foo_%d", i);
    ht_find_new(ht1, buf)->val = i;
    }

    for (i=0; i<n; ++i) {
    for (node=ht_first(ht1); node; node=ht_next(ht1)) {
        ht_find_new(ht2, node->key)->val += node->val;
    }
    }

    printf("%d %d %d %d\n",
       (ht_find(ht1, "foo_1"))->val,
       (ht_find(ht1, "foo_9999"))->val,
       (ht_find(ht2, "foo_1"))->val,
       (ht_find(ht2, "foo_9999"))->val);

    ht_destroy(ht1);
    ht_destroy(ht2);
    return(0);
}
hash2.gforth
\ -*- mode: forth -*-
\ $Id: hash2.gforth,v 1.1 2001/05/25 21:32:46 doug Exp $
\ http://www.bagley.org/~doug/shootout/
\ from Anton Ertl:


0. argc @ 1- arg >number 2drop drop constant NUM

wordlist constant hash1
wordlist constant hash2

: build 
    get-current hash1 set-current
    10000 0 ?do
    i 0 <# #s '_ hold 'o hold 'o hold 'f hold #> nextname i constant
    loop
    set-current ;

: search-new 
    >r 2dup r@ search-wordlist if
    rdrop nip nip
    else
    nextname get-current r> set-current 0 constant set-current
    lastxt
    endif ;

: add-to-hash2 
    dup name>int execute 
    swap name>string hash2 search-new >body +! ;

: build2 
    hash1 wordlist-id begin
    @ dup
    while
    dup add-to-hash2
    repeat
    drop ;

: countdecs 
    NUM 0 ?do
    build2
    loop ;

build countdecs

hash1 >order
foo_1 .
foo_9999 .
previous

hash2 >order
foo_1 .
foo_9999 0 .r cr
previous bye
hash2.guile
#!/usr/local/bin/guile \
-e main -s
!#

;;; $Id: hash2.guile,v 1.3 2001/06/29 23:12:37 doug Exp $
;;; http://www.bagley.org/~doug/shootout/

(use-modules (ice-9 format))

(define (main args)
  (let* ((n (or (and (= (length args) 2) (string->;number (cadr args))) 1))
     (hash1 (make-hash-table 10000))
     (hash2 (make-hash-table 10000)))
    (do ((i 0 (+ i 1)))
    ((= i 10000))
      (hash-set! hash1 (string-append "foo_" (number->;string i 10)) i))
    (do ((i 0 (+ i 1)))
    ((= i n))
      (hash-fold (lambda (key val init)
           (hash-set! hash2 key (+ (hash-ref hash2 key 0)
                       (hash-ref hash1 key))))
         '() hash1))
    (display (format "~D ~D ~D ~D\n"
             (hash-ref hash1 "foo_1")
             (hash-ref hash1 "foo_9999")
             (hash-ref hash2 "foo_1")
             (hash-ref hash2 "foo_9999")))))
hash2.ici
// $Id: hash2.ici,v 1.0 2003/01/03 11:46:00 dada Exp $
// http://dada.perl.it/shootout
//
// contributed by Tim Long

n = argv[1] ? int(argv[1]) : 1;

h1 = struct();
for (i = 0; i < 10000; ++i)
    h1[sprintf("foo_%d", i)] = i;

h2 = struct();
for (i = 0; i < n; ++i)
{
    forall (v, k in h1)
    {
        if (h2[k] == NULL)
            h2[k] = 0;
        h2[k] += h1[k];
    }
}

printf("%d %d %d %d\n", h1["foo_1"], h1["foo_9999"], h2["foo_1"], h2["foo_9999"]);
hash2.icon
# -*- mode: icon -*-
# $Id: hash2.icon,v 1.1 2000/12/30 06:30:12 doug Exp $
# http://www.bagley.org/~doug/shootout/

procedure main(argv)
    n := argv[1] | 1
    hash1 := table(0)
    hash2 := table(0)
    every i := 0 to 10000 do {
    hash1["foo_"||string(i)] := i
    }
    every i := 1 to n do
    every k := key(hash1) do
        hash2[k] +:= hash1[k]
    write(hash1["foo_1"], " ", hash1["foo_9999"], " ",
      hash2["foo_1"], " ", hash2["foo_9999"])
end
hash2.java
// $Id: hash2.java,v 1.3 2001/05/31 20:37:44 doug Exp $
// http://www.bagley.org/~doug/shootout/

import java.util.*;

class Val {
    int val;
    Val(int init) { val = init; }
}

public class hash2 {
    public static void main(String args[]) {
    int n = Integer.parseInt(args[0]);
    HashMap hash1 = new HashMap(10000);
    HashMap hash2 = new HashMap(n);

    for(int i = 0; i < 10000; i++)
        hash1.put("foo_" + Integer.toString(i, 10), new Val(i));
    for(int i = 0; i < n; i++) {
        Iterator it = hash1.entrySet().iterator();
        while(it.hasNext()) {
            Map.Entry h1 = (Map.Entry)it.next();
            String key = (String)h1.getKey();
            int v1 = ((Val)h1.getValue()).val;
            if (hash2.containsKey(key))
                ((Val)hash2.get(key)).val += v1;
            else
                hash2.put(key, new Val(v1));
        }
    }

    System.out.print(((Val)hash1.get("foo_1")).val    + " " +
                     ((Val)hash1.get("foo_9999")).val + " " +
                     ((Val)hash2.get("foo_1")).val    + " " +
                     ((Val)hash2.get("foo_9999")).val + "\n");
    }
}
hash2.jscript
// -*- mode: java -*-
// $Id: hash2.njs,v 1.1 2001/07/10 02:39:11 doug Exp $
// http://www.bagley.org/~doug/shootout/
// by David Hedbor <david@hedbor.org>
// modified by Aldo Calpini <dada@perl.it> for Win32

var n;
ARGS = WScript.Arguments;
if(ARGS.length > 0) {
  n = parseInt(ARGS.Item(0), "10");
  if(n < 1) n = 1;
} else {   
  n = 150;
}

var hash1 = Object();
var hash2 = Object();
var arr = Array(10000);
var idx;

for (i=0; i<10000; i++) {
  idx = "foo_"+i;
  hash1[idx] = i;
  // Do this here and run loop below one less since += on an undefined
  // entry == NaN.
  hash2[idx] = hash1[idx];
}

for (i = 1; i < n; i++) {
  for(a in hash1) {
    hash2[a] += hash1[a];
  }
}

WScript.Echo(hash1["foo_1"], hash1["foo_9999"],
             hash2["foo_1"], hash2["foo_9999"]);

hash2.lcc
/* -*- mode: c -*-
 * $Id: hash2.gcc,v 1.3 2001/01/07 16:23:00 doug Exp $
 * http://www.bagley.org/~doug/shootout/
 */

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include "simple_hash.h"

int main(int argc, char *argv[]) {
    int i, n = ((argc == 2) ? atoi(argv[1]) : 1);
    char buf[32];
    struct ht_ht *ht1 = ht_create(10000);
    struct ht_ht *ht2 = ht_create(10000);
    struct ht_node *node;

    for (i=0; i<=9999; ++i) {
    sprintf(buf, "foo_%d", i);
    ht_find_new(ht1, buf)->val = i;
    }

    for (i=0; i<n; ++i) {
    for (node=ht_first(ht1); node; node=ht_next(ht1)) {
        ht_find_new(ht2, node->key)->val += node->val;
    }
    }

    printf("%d %d %d %d\n",
       (ht_find(ht1, "foo_1"))->val,
       (ht_find(ht1, "foo_9999"))->val,
       (ht_find(ht2, "foo_1"))->val,
       (ht_find(ht2, "foo_9999"))->val);

    ht_destroy(ht1);
    ht_destroy(ht2);
    return(0);
}
hash2.lua
-- $Id: hash2.lua,v 1.2 2001/01/11 14:52:55 doug Exp $
-- http://www.bagley.org/~doug/shootout/
-- with help from Roberto Ierusalimschy

local n = tonumber((arg and arg[1]) or 1)

local hash1={}
for i=0,10000 do
    hash1["foo_"..i] = i
end
local hash2={}
for i=1,n do
    for k,v in hash1 do
    hash2[k] = v + (hash2[k] or 0)
    end
end

write(format("%d %d %d %d\n", hash1["foo_1"], hash1["foo_9999"],
         hash2["foo_1"], hash2["foo_9999"]))
hash2.lua5
-- $Id: hash2.lua,v 1.2 2001/01/11 14:52:55 doug Exp $
-- http://www.bagley.org/~doug/shootout/
-- contributed by Roberto Ierusalimschy

local n = tonumber((arg and arg[1]) or 1)

local hash1={}
for i=1,10000 do
    hash1["foo_"..i] = i
end
local hash2={}
for i=1,n do
  for k,v in pairs(hash1) do
    hash2[k] = v + (hash2[k] or 0)
  end
end

io.write(string.format("%d %d %d %d\n", hash1["foo_1"], hash1["foo_9999"],
         hash2["foo_1"], hash2["foo_9999"]))

hash2.mawk
# $Id: hash2.mawk,v 1.2 2001/05/20 06:13:00 doug Exp $
# http://www.bagley.org/~doug/shootout/

BEGIN {
    n = (ARGV[1] < 1) ? 1 : ARGV[1];

    for (i=0; i<10000; i++)
    hash1[sprintf("foo_%d", i)] = i
    for (i=0; i<n; i++)
    for (k in hash1)
        hash2[k] += hash1[k]
    print hash1["foo_1"], hash1["foo_9999"], hash2["foo_1"], hash2["foo_9999"]
}
hash2.mingw32
/* -*- mode: c -*-
 * $Id: hash2.gcc,v 1.3 2001/01/07 16:23:00 doug Exp $
 * http://www.bagley.org/~doug/shootout/
 */

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include "simple_hash.h"

int main(int argc, char *argv[]) {
    int i, n = ((argc == 2) ? atoi(argv[1]) : 1);
    char buf[32];
    struct ht_ht *ht1 = ht_create(10000);
    struct ht_ht *ht2 = ht_create(10000);
    struct ht_node *node;

    for (i=0; i<=9999; ++i) {
    sprintf(buf, "foo_%d", i);
    ht_find_new(ht1, buf)->val = i;
    }

    for (i=0; i<n; ++i) {
    for (node=ht_first(ht1); node; node=ht_next(ht1)) {
        ht_find_new(ht2, node->key)->val += node->val;
    }
    }

    printf("%d %d %d %d\n",
       (ht_find(ht1, "foo_1"))->val,
       (ht_find(ht1, "foo_9999"))->val,
       (ht_find(ht2, "foo_1"))->val,
       (ht_find(ht2, "foo_9999"))->val);

    ht_destroy(ht1);
    ht_destroy(ht2);
    return(0);
}
hash2.nice
/* The Great Win32 Language Shootout http://dada.perl.it/shootout/ 
   contributed by Isaac Gouy (Nice novice)

To compile:	
   nicec --sourcepath=.. -d=. -a hash2.jar hash2

To run:
   java -jar hash2.jar 150
*/


import ackermann; // reuse toSingleInt


void main(String[] args){
   var n = toSingleInt(args);
   let nKeys = 10000;

   HashMap table1 = new HashMap(nKeys);
   HashMap table2 = new HashMap();

   for (var i = 0; i <= nKeys; i++) 
      table1.put( "foo_" + toString(i), new Cell(value: i) );

   String key;
   int v1;        
   ?Cell c2;      // c2 = table2.get(key) can be null 

   while (n-- > 0) {
      Iterator> item = table1.entrySet().iterator();
      while(item.hasNext()) {
         Map.Entry e = item.next();
         key = e.getKey();
         v1 = e.getValue().value;                       
         if ( (c2 = table2.get(key)) != null)
            c2.value += v1;   
         else 
            table2.put(key, new Cell(value: v1) );
      }
   }
   print( toString( table1.get("foo_1") )); print(" ");
   print( toString( table1.get("foo_9999") )); print(" ");
   print( toString( table2.get("foo_1") )); print(" ");
   println( toString( table2.get("foo_9999") )); 
}


class Cell { int value; }

String toString(?Cell c) {
   if (c==null) return "null"; else return toString(c.value);
}
hash2.ocaml
(*
 * $Id: hash2.ocaml,v 1.3 2001/01/08 13:21:09 doug Exp $
 * http://www.bagley.org/~doug/shootout/
 * with help from Markus Mottl
 *)

let _ =
  let n =
    try int_of_string Sys.argv.(1)
    with Invalid_argument _ -> 1
  and hash1 = Hashtbl.create 10000 in
  for i = 0 to 9999 do
    Hashtbl.add hash1 ("foo_" ^ string_of_int i) (ref i)
  done;
  let hash2 = Hashtbl.create 10000 in
  let update_hash2 k v =
    try
      let valref = Hashtbl.find hash2 k in
      valref := !valref + !v
    with Not_found -> Hashtbl.add hash2 k (ref !v) in
  for i = 1 to n do
    Hashtbl.iter update_hash2 hash1
  done;
  Printf.printf "%d %d %d %d\n"
    !(Hashtbl.find hash1 "foo_1")
    !(Hashtbl.find hash1 "foo_9999")
    !(Hashtbl.find hash2 "foo_1")
    !(Hashtbl.find hash2 "foo_9999")
hash2.ocamlb
(*
 * $Id: hash2.ocaml,v 1.3 2001/01/08 13:21:09 doug Exp $
 * http://www.bagley.org/~doug/shootout/
 * with help from Markus Mottl
 *)

let _ =
  let n =
    try int_of_string Sys.argv.(1)
    with Invalid_argument _ -> 1
  and hash1 = Hashtbl.create 10000 in
  for i = 0 to 9999 do
    Hashtbl.add hash1 ("foo_" ^ string_of_int i) (ref i)
  done;
  let hash2 = Hashtbl.create 10000 in
  let update_hash2 k v =
    try
      let valref = Hashtbl.find hash2 k in
      valref := !valref + !v
    with Not_found -> Hashtbl.add hash2 k (ref !v) in
  for i = 1 to n do
    Hashtbl.iter update_hash2 hash1
  done;
  Printf.printf "%d %d %d %d\n"
    !(Hashtbl.find hash1 "foo_1")
    !(Hashtbl.find hash1 "foo_9999")
    !(Hashtbl.find hash2 "foo_1")
    !(Hashtbl.find hash2 "foo_9999")
hash2.oz
%%% $Id: hash2.oz,v 1.0 2002/08/19 16:26:00 dada Exp $
%%% http://dada.perl.it/shootout/
%%% 
%%% contributed by Isaac Gouy

%%  Usage: start from command line with
%%     ozc -x hash2.oz -o hash2.oz.exe
%%     hash2.oz.exe 150

functor
import System Application

define

proc {InitHash H}
   for I in 0..9999 do 
      {Dictionary.put H
         {String.toAtom {List.append "foo_" {IntToString I}}} I} 
   end
end

proc {AddValues L H}
   local Key Value Tail V in
      if L \= nil then
         (Key#Value|Tail) = L
         {Dictionary.condGet H Key nil V}
         if V == nil then
            {Dictionary.put H Key Value}
         else
            {Dictionary.put H Key Value+V}
         end
         {AddValues Tail H}
      end
   end
end

in 
   local Args N H1 H2 in
      [Args] = {Application.getArgs plain}
      N = {String.toInt Args}

      {NewDictionary H1}
      {NewDictionary H2}

      {InitHash H1}
      for I in 1..N do 
         {AddValues {Dictionary.entries H1} H2} end

      {System.printInfo {Dictionary.get H1 'foo_1'}}
      {System.printInfo ' '}
      {System.printInfo {Dictionary.get H1 'foo_9999'}}
      {System.printInfo ' '}
      {System.printInfo {Dictionary.get H2 'foo_1'}}
      {System.printInfo ' '}
      {System.printInfo {Dictionary.get H2 'foo_9999'}}
   end
   {Application.exit 0}
end

hash2.parrot
# $Id: hash2.parrot,v 1.0 2002/08/19 17:25:00 dada Exp $
# http://dada.perl.it/shootout/

    set I1, P0[1]
    
    set I2, 0

    new P1, .PerlHash
    new P11, .PerlArray
    set P11, 10000

HASH1:
    set S0, "foo_"
    set S1, I2
    concat S0, S1
    set P1[S0], I2
    set P11[I2], S0
    inc I2
    lt I2, 10000, HASH1

    new P2, .PerlHash    

    set I0, 1
HASH2:
        
    set I3, P11
    set I2, 0
HASH1_KEYS:

    set S0, P11[I2]
    set I4, P1[S0]
    set I5, P2[S0]
    add I5, I4
    set P2[S0], I5
    
    inc I2
    le I2, I3, HASH1_KEYS
    
    inc I0
    le I0, I1, HASH2


    set S0, "foo_1"
    set I0, P1[S0]
    set S1, I0
    print S1
    print " "
    set S0, "foo_9999"
    set I0, P1[S0]
    set S1, I0
    print S1
    print " "
    set S0, "foo_1"
    set I0, P2[S0]
    set S1, I0
    print S1
    print " "
    set S0, "foo_9999"
    set I0, P2[S0]
    set S1, I0
    print S1
    end
hash2.perl
#!/usr/local/bin/perl
# $Id: hash2.perl,v 1.3 2001/01/18 23:38:26 doug Exp $
# http://www.bagley.org/~doug/shootout/
# with help from Steve Fink

use strict;

my $n = ($ARGV[0] > 0) ? $ARGV[0] : 1;
my %hash1 = ();
$hash1{"foo_$_"} = $_ for 0..9999;
my %hash2 = ();
my($k, $v);
for (1..$n) {
    $hash2{$_} += $hash1{$_} while (defined ($_ = each %hash1));
}
print "$hash1{foo_1} $hash1{foo_9999} $hash2{foo_1} $hash2{foo_9999}\n";
hash2.php
<?php
/*
 $Id: hash2.php,v 1.1 2001/05/06 05:29:12 doug Exp $
 http://www.bagley.org/~doug/shootout/
*/
$n = ($argc == 2) ? $argv[1] : 1;
for ($i = 0; $i < 10000; $i++) {
    $hash1["foo_$i"] = $i;
}
for ($i = $n; $i > 0; $i--) {
    foreach($hash1 as $key => $value) $hash2[$key] += $value;
}
print "$hash1[foo_1] $hash1[foo_9999] $hash2[foo_1] $hash2[foo_9999]\n";
?>
hash2.pike
#!/usr/local/bin/pike// -*- mode: pike -*-
// $Id: hash2.pike,v 1.2 2001/01/02 07:11:13 doug Exp $
// http://www.bagley.org/~doug/shootout/

void main(int argc, array(string) argv) {
    int n = (int)argv[-1];
    if (n < 1) n = 1;
      
    mapping(string:int) hash1 = ([]);
    mapping(string:int) hash2 = ([]);
    for (int i=0; i<10000; i++)
    hash1["foo_" + i] = i;
    for (int i=0; i<n; i++) {
    foreach (indices(hash1), string k) {
        hash2[k] += hash1[k];
    }
    }
    write("%d %d %d %d\n", hash1["foo_1"], hash1["foo_9999"],
      hash2["foo_1"], hash2["foo_9999"]);
}
hash2.pliant
# $Id: hash.pliant,v 1.0 2002/02/07 14:45:00 dada Exp $
# http://dada.perl.it/shootout/

module "/pliant/language/context.pli"

gvar (Index Str Int) hash1
gvar (Dictionary Str Int) hash2
gvar Str k
gvar Int i
gvar Pointer:Int v
gvar Str s_n := cast ((pliant_script_args translate Address 1) map CStr) Str
if (s_n parse (gvar Int n))
  for (i) 0 9999
    hash1 insert "foo_"+(string i) i
  for (i) 1 n
    v :> hash1 first
    k := hash1 key v    
    if addressof:(hash2 first k)<>null
      hash2:k += hash1:k
    else
      hash2 insert k hash1:k
    while addressof:v<>null
      if addressof:(hash2 first k)<>null
        hash2:k += hash1:k
      else
        hash2 insert k hash1:k
      v :> hash1 next v
      if addressof:v<>null
        k := hash1 key v
  console hash1:"foo_1" " " hash1:"foo_9999" " " hash2:"foo_1" " " hash2:"foo_9999" eol
else
  console "usage: hash2.pliant <number>" eol
hash2.poplisp
;;; -*- mode: lisp -*-
;;; $Id: hash2.cmucl,v 1.4 2001/06/26 03:19:55 doug Exp $
;;; http://www.bagley.org/~doug/shootout/
;;; from Paul Foley

(declaim (optimize (speed 3) (space 0) (safety 0) (debug 0) (compilation-speed 0)))
(defun command-line-argument ()
  (parse-integer (or (car pop11::poparglist) "1")))

(defconstant +digit+ "0123456789")

(defconstant +digits-needed+
  '(10 100 1000 10000 100000 10000000 100000000 536870911))

(defun fixnum-to-foo-string (n)
  (declare (fixnum n))
  (let* ((size (+ 4 (position-if (lambda (x) (>; (the fixnum x) n))
                                 +digits-needed+)))
     (result (make-string (1+ size))))
    (replace result "foo_")
    (loop for i fixnum from size downto 4 with q fixnum = n and r fixnum = 0
      do (multiple-value-setq (q r) (floor q 10))
         (setf (schar result i) (aref +digit+ r)))
    result))

(defun main (&optional (n (command-line-argument)))
  (let ((hash1 (make-hash-table :test 'equal :size n))
        (hash2 (make-hash-table :test 'equal :size n)))
    (macrolet ((hash1 (i) `(gethash (fixnum-to-foo-string ,i) hash1))
               (hash2 (i) `(gethash (fixnum-to-foo-string ,i) hash2)))
      (loop for i fixnum below 10000 do (setf (hash1 i) i))
      (loop for i fixnum below n do
        (maphash (lambda (k v)
                   (declare (fixnum v))
                   (incf (the fixnum (gethash k hash2 0)) v))
                 hash1))
      (format t "~D ~D ~D ~D~%" (hash1 1) (hash1 9999) (hash2 1) (hash2 9999)))))

(main)
hash2.python
#!/usr/local/bin/python
# $Id: hash2.python,v 1.2 2001/05/06 19:16:31 doug Exp $
# http://www.bagley.org/~doug/shootout/
# from Mark Baker

import sys

n = int(sys.argv[1])
hash1 = {}
for i in xrange(10000):
    hash1['foo_' + `i`] = i

hash2 = {}
for i in xrange(n):
    for k in hash1.keys():
        try:
            hash2[k] += hash1[k]
        except KeyError:
            hash2[k] = hash1[k]

print hash1['foo_1'], hash1['foo_9999'], hash2['foo_1'], hash2['foo_9999']

hash2.rebol
REBOL [
    Title:   "Hash2"
    Author:  "Aldo Calpini"
    Date:    05-Jul-2001
    File:    %hash2.r
]

NUM: to-integer to-string system/script/args
NUM: either NUM < 1 [ 1 ] [ NUM ]

hash1: make [] 9999

for i 0 9999 1 [
    append hash1 rejoin [ "foo_" i ]
    append hash1 i
]

hash2: make [] 9999

for i 1 NUM 1 [

    hash1: head hash1
    forskip hash1 2 [
        k: first hash1
        hash2: head hash2
        k2: select/skip hash2 k 2 
        either k2 == none [
            append hash2 k
            append hash2 0
            v: 0
            hash2: head hash2
            hash2: find/skip hash2 k 2
        ] [
            hash2: find/skip hash2 k 2
            v: second hash2
        ]
        v1: first select/skip hash1 k 2        
        v2: (v + v1)
        comment [
            hash2: head hash2
            hash2: find/skip hash2 k 2         
            hash2: next hash2
        ]
        hash2: next hash2
        change hash2 v2
        comment [        
            if error? try [ change hash2 v2 ] [ 
                print [ "error in change hash2 (k=" k ")" ]
                probe hash2 
            ]
        ]
    ]
    hash2: head hash2
]

hash1: head hash1
hash2: head hash2

write %output.rebol [ 
    select/skip hash1 "foo_1" 2
    select/skip hash1 "foo_9999" 2
    select/skip hash2 "foo_1" 2
    select/skip hash2 "foo_9999" 2
]
hash2.rexx
parse arg n
If n < 1 Then Do
    n = 1
End

keys.0 = 10000
Do i = 0 To 9999
    k = "FOO_"i
    hash1.k = i
    ki = i + 1
    keys.ki = k
End

hash2. = 0
Do i = 1 To n
    Do j = 1 To keys.0
        k = keys.j
        hash2.k = hash2.k + hash1.k    
    End
End

Say hash1.FOO_1" "hash1.FOO_9999" "hash2.FOO_1" "hash2.FOO_9999
hash2.ruby
#!/usr/local/bin/ruby
# -*- mode: ruby -*-
# $Id: hash2.ruby,v 1.2 2001/05/16 16:17:08 doug Exp $
# http://www.bagley.org/~doug/shootout/

n = Integer(ARGV.shift || 1)

hash1 = {}
for i in 0 .. 9999
    hash1["foo_" << i.to_s] = i
end

hash2 = Hash.new(0)
n.times do
    for k in hash1.keys
    hash2[k] += hash1[k]
    end
end

printf "%d %d %d %d\n",
    hash1["foo_1"], hash1["foo_9999"], hash2["foo_1"], hash2["foo_9999"]
hash2.se
-- -*- mode: eiffel -*-
-- $Id: hash2.se,v 1.2 2001/04/26 07:23:16 doug Exp $
-- http://www.bagley.org/~doug/shootout/

class HASH2
   
creation make
   
feature -- Initialization
   
   make is
      local
     n, i, prev : INTEGER
     hash1 : DICTIONARY[INTEGER, STRING]
     hash2 : DICTIONARY[INTEGER, STRING]
     it: ITERATOR[STRING]
      do
     n := argument(1).to_integer

     !!hash1.with_capacity(10000);
     !!hash2.with_capacity(10000);
     
     -- std_output.put_string("building hash1")
     -- std_output.put_character('%N')
     from  i := 0
     until i = 10000
     loop
        -- std_output.put_integer(i)
        -- std_output.put_character('%N')
        hash1.put(i, "foo_" + i.to_string)
        i := i + 1
     end

     from  i := 0
     until i = n
     loop
        -- std_output.put_string("building hash2")
        -- std_output.put_character('%N')
        it := hash1.get_new_iterator_on_keys
        from  it.start
        until it.is_off
        loop
           if hash2.has(it.item) then
          prev := hash2.at(it.item)
           else
          prev := 0
           end
           hash2.put(prev + hash1.at(it.item), it.item)
           it.next;
        end
        i := i + 1
     end

         std_output.put_integer(hash1.at("foo_1"))
         std_output.put_string(" ")
         std_output.put_integer(hash1.at("foo_9999"))
         std_output.put_string(" ")
         std_output.put_integer(hash2.at("foo_1"))
         std_output.put_string(" ")
         std_output.put_integer(hash2.at("foo_9999"))
         std_output.put_character('%N')
      end

end -- class HASH2

hash2.slang
% $Id: hash2.slang,v 1.0 2003/01/03 14:09:00 dada Exp $
% http://dada.perl.it/shootout/
%
% contributed by John E. Davis

_auto_declare=1;
n = integer(__argv[1]);
hash1 = Assoc_Type[Int_Type];
_for (1, 10000, 1)
{
   i = ();
   hash1[strcat ("foo_", string(i))] = i;
}

hash2 = Assoc_Type[Int_Type, 0];
loop (n)
{
   foreach (hash1) using ("keys", "values")
     {
    (k,v) = ();
    hash2[k] += v;
     }
}

vmessage ("%d %d %d %d",
      hash1["foo_1"], hash1["foo_9999"], hash2["foo_1"], hash2["foo_9999"]);


hash2.smlnj
(* -*- mode: sml -*-
 * $Id: hash2.smlnj,v 1.3 2001/07/10 13:01:54 doug Exp $
 * http://www.bagley.org/~doug/shootout/
 * Modified by Daniel Wang
 *)

structure Test : sig
    val main : (string * string list) -> OS.Process.status
end = struct

open HashTable;

fun hashtest2 n =
    let
    exception NotFound
    val h1 = mkTable (HashString.hashString, op =) (10000, NotFound)
    val h2 = mkTable (HashString.hashString, op =) (10000, NotFound)
    fun doinserts1 i =
        if i < 10000 then (
        insert h1 ("foo_" ^ (Int.toString i), i);
        doinserts1 (i+1)
        ) else ()
    fun addinto h k v1 =
        case find h k of
        SOME valref => valref := (!valref) + v1
          | NONE => insert h (k, ref v1)
    fun doinserts2 i =
        if i < n then (
        appi (fn (k,v) => (addinto h2 k v)) h1;
        doinserts2 (i+1)
        ) else ()
    in (
    doinserts1 0;
    doinserts2 0;
    print (Int.toString (lookup h1 "foo_1")); print " ";
    print (Int.toString (lookup h1 "foo_9999")); print " ";
    print (Int.toString (!(lookup h2 "foo_1"))); print " ";
    print (Int.toString (!(lookup h2 "foo_9999")));
    print "\n"
    ) end;

fun atoi s = case Int.fromString s of SOME num => num | NONE => 0;

fun main(name, args) = 
    let
    val arg = hd(args @ ["1"])
    val num = atoi arg
    in
    hashtest2 num;
    OS.Process.success
    end
end

val _ = SMLofNJ.exportFn("hash2", Test.main);
hash2.tcl
#!/usr/local/bin/tclsh
# $Id: hash2.tcl,v 1.6 2001/05/18 06:35:40 doug Exp $
# http://www.bagley.org/~doug/shootout/
# with help from Branko Vesligaj

proc main {} {
    global argv
    set n [lindex $argv 0]
    for {set i 0} {$i < 10000} {incr i} {
    set hash1(foo_$i) $i
    }
    for {set i $n} {$i > 0} {incr i -1} {
    foreach k [array names hash1] {
        if {[catch {set hash2($k) [expr {$hash1($k) + $hash2($k)}]}]} {
        set hash2($k) $hash1($k)
        }
    }
    }
    puts [join [list $hash1(foo_1) $hash1(foo_9999) $hash2(foo_1) $hash2(foo_9999) ] " "]
}

main
hash2.vbscript
n = WScript.Arguments(0)
If n < 1 Then n = 1

Set hash1 = CreateObject("Scripting.Dictionary")
For i = 0 To 9999
    hash1.Add "foo_" & i, i
Next

Set hash2 = CreateObject("Scripting.Dictionary")
For i = 1 To N
    For Each k In hash1.Keys
        If Not hash2.Exists(k) Then
            hash2.Add k, 0
        End If
        hash2.Item(k) = hash2.Item(k) + hash1.Item(k)
    Next
Next

WScript.Echo hash1.Item("foo_1") & " " & hash1.Item("foo_9999") & " " & hash2.Item("foo_1") & " " & hash2.Item("foo_9999")
hash2.vc
/* -*- mode: c -*-
 * $Id: hash2.gcc,v 1.3 2001/01/07 16:23:00 doug Exp $
 * http://www.bagley.org/~doug/shootout/
 */

#include <stdio.h>
#include <stdlib.h>
#include "simple_hash.vc.h"

int main(int argc, char *argv[]) {
    int i, n = ((argc == 2) ? atoi(argv[1]) : 1);
    char buf[32];
    struct ht_ht *ht1 = ht_create(10000);
    struct ht_ht *ht2 = ht_create(10000);
    struct ht_node *node;

    for (i=0; i<=9999; ++i) {
    sprintf(buf, "foo_%d", i);
    ht_find_new(ht1, buf)->val = i;
    }

    for (i=0; i<n; ++i) {
    for (node=ht_first(ht1); node; node=ht_next(ht1)) {
        ht_find_new(ht2, node->key)->val += node->val;
    }
    }

    printf("%d %d %d %d\n",
       (ht_find(ht1, "foo_1"))->val,
       (ht_find(ht1, "foo_9999"))->val,
       (ht_find(ht2, "foo_1"))->val,
       (ht_find(ht2, "foo_9999"))->val);

    ht_destroy(ht1);
    ht_destroy(ht2);
    return(0);
}
hash2.vc++
// -*- mode: c++ -*-
// $Id: hash2.g++,v 1.2 2001/06/20 03:20:02 doug Exp $
// http://www.bagley.org/~doug/shootout/

#include <stdio.h>
#include <iostream>
#include <hash_map.h>

using namespace std;

struct eqstr {
    bool operator()(const char* s1, const char* s2) const {
    return strcmp(s1, s2) == 0;
    }
};

int
main(int argc, char *argv[]) {
    int n = ((argc == 2) ? atoi(argv[1]) : 1);
    char buf[16];
    typedef hash_map<const char*, int, hash<const char*>, eqstr> HM;
    HM hash1, hash2;

    for (int i=0; i<10000; i++) {
    sprintf(buf, "foo_%d", i);
    hash1[strdup(buf)] = i;
    }
    for (int i=0; i<n; i++) {
    for (HM::iterator k = hash1.begin(); k != hash1.end(); ++k) {
        hash2[(*k).first] += hash1[(*k).first];
    }
    }
    cout << hash1["foo_1"] << " " << hash1["foo_9999"] << " "
     << hash2["foo_1"] << " " << hash2["foo_9999"] << endl;
}