[MLton] cvs commit: new implementation of alphaNumChar

Stephen Weeks sweeks@mlton.org
Sun, 28 Dec 2003 16:05:46 -0800


sweeks      03/12/28 16:05:46

  Modified:    basis-library/mlton random.sml
               lib/mlton-stubs random.sml
  Log:
  MAIL new implementation of alphaNumChar
  
  Used Matthew's suggestion to cut down the number of tests per char
  from two to one, and cut down the total number of rand calls by one
  per program.
  
  I also added a very explicit computation of refresh.  Please check it
  out.

Revision  Changes    Path
1.9       +17 -8     mlton/basis-library/mlton/random.sml

Index: random.sml
===================================================================
RCS file: /cvsroot/mlton/mlton/basis-library/mlton/random.sml,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -r1.8 -r1.9
--- random.sml	28 Dec 2003 23:15:00 -0000	1.8
+++ random.sml	29 Dec 2003 00:05:46 -0000	1.9
@@ -61,22 +61,31 @@
       local
 	 val chars =
 	    "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
+	 val numChars = String.size chars
 	 val refresh =
-	    Int.quot (Word.wordSize,
-		      1 + IntInf.log2 (IntInf.fromInt (String.size chars)))
-	 val r: word ref = ref (rand ())
-	 val count: int ref = ref 0
-	 val numChars = Word.fromInt (String.size chars)
+	    let
+	       val numChars = IntInf.fromInt numChars
+	       fun loop (i: IntInf.int, c: int): int =
+		  if IntInf.< (i, numChars)
+		     then c
+		  else loop (IntInf.div (i, numChars), c + 1)
+	    in
+	       loop (IntInf.pow (2, Word.wordSize), 0)
+	    end
+	 val r: word ref = ref 0w0
+	 val count: int ref = ref refresh
+	 val numChars = Word.fromInt numChars
       in
 	 fun alphaNumChar (): char =
 	    let
 	       val n = !count
-	       val _ = if 0 = n then r := rand () else ()
+	       val _ = if n = refresh
+			  then (r := rand ()
+				; count := 1)
+		       else (count := n + 1)
 	       val w = !r
 	       val c = String.sub (chars, Word.toInt (Word.mod (w, numChars)))
 	       val _ = r := Word.div (w, numChars)
-	       val n = n + 1
-	       val _ = count := (if n = refresh then 0 else n)
 	    in
 	       c
 	    end



1.5       +17 -8     mlton/lib/mlton-stubs/random.sml

Index: random.sml
===================================================================
RCS file: /cvsroot/mlton/mlton/lib/mlton-stubs/random.sml,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- random.sml	28 Dec 2003 23:15:01 -0000	1.4
+++ random.sml	29 Dec 2003 00:05:46 -0000	1.5
@@ -27,22 +27,31 @@
       local
 	 val chars =
 	    "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
+	 val numChars = String.size chars
 	 val refresh =
-	    Int.quot (Word.wordSize,
-		      1 + IntInf.log2 (IntInf.fromInt (String.size chars)))
-	 val r: word ref = ref (rand ())
-	 val count: int ref = ref 0
-	 val numChars = Word.fromInt (String.size chars)
+	    let
+	       val numChars = IntInf.fromInt numChars
+	       fun loop (i: IntInf.int, c: int): int =
+		  if IntInf.< (i, numChars)
+		     then c
+		  else loop (IntInf.div (i, numChars), c + 1)
+	    in
+	       loop (IntInf.pow (2, Word.wordSize), 0)
+	    end
+	 val r: word ref = ref 0w0
+	 val count: int ref = ref refresh
+	 val numChars = Word.fromInt numChars
       in
 	 fun alphaNumChar (): char =
 	    let
 	       val n = !count
-	       val _ = if 0 = n then r := rand () else ()
+	       val _ = if n = refresh
+			  then (r := rand ()
+				; count := 1)
+		       else (count := n + 1)
 	       val w = !r
 	       val c = String.sub (chars, Word.toInt (Word.mod (w, numChars)))
 	       val _ = r := Word.div (w, numChars)
-	       val n = n + 1
-	       val _ = count := (if n = refresh then 0 else n)
 	    in
 	       c
 	    end