[m-dev.] diff: improve efficiency of random__permutation

Fergus Henderson fjh at cs.mu.OZ.AU
Mon Sep 25 19:24:33 AEDT 2000


Estimated hours taken: 0.75

library/random.m:
	Improve efficiency of random__permutation:
		- use an array rather than a map
		- use `rem' rather than `div'

Workspace: /home/mercury0/fjh/mercury
Index: library/random.m
===================================================================
RCS file: /home/mercury1/repository/mercury/library/random.m,v
retrieving revision 1.18
diff -u -d -r1.18 random.m
--- library/random.m	2000/02/16 08:17:54	1.18
+++ library/random.m	2000/09/25 08:17:47
@@ -65,7 +65,7 @@
 %---------------------------------------------------------------------------%
 
 :- implementation.
-:- import_module int, map.
+:- import_module int, array.
 
 :- type random__supply		==	int.	% I(j)
 
@@ -90,7 +90,7 @@
 %---------------------------------------------------------------------------%
 
 	% The random permutation is implemented via a "sampling without
-	% replacement" method. In init_record, we build up a map in which
+	% replacement" method. In init_record, we build up an array in which
 	% every integer in the range 0 .. Length - 1 is mapped to the
 	% corresponding element in the list.  The sampling stage
 	% iterates from Length - 1 down to 0. The invariant being
@@ -102,20 +102,11 @@
 	% Next is not generated again by swapping it with the image of I-1.
 
 random__permutation(List0, List, RS0, RS) :-
-	map__init(Samples0),
-	init_record(List0, 0, Samples0, Len, Samples),
+	Samples = array(List0),
+	Len = array__size(Samples),
 	perform_sampling(Len, Samples, [], List, RS0, RS).
 
-:- pred init_record(list(T)::in, int::in, map(int, T)::in, 
-		int::out, map(int, T)::out) is det.
-
-init_record([], N, Record, N, Record).
-init_record([X|Xs], N0, Record0, N, Record) :-
-	map__det_insert(Record0, N0, X, Record1),
-	N1 = N0 + 1,
-	init_record(Xs, N1, Record1, N, Record).
-
-:- pred perform_sampling(int::in, map(int, T)::in,
+:- pred perform_sampling(int::in, array(T)::array_di,
 	list(T)::in, list(T)::out,
 	random__supply::mdi, random__supply::muo) is det.
 
@@ -126,12 +117,14 @@
 	;
 		I1 = I - 1,
 		random__random(Random, RS0, RS1),
-		Index = Random mod I,
-		map__lookup(Record0, Index, Next),
-		map__lookup(Record0, I1, MaxImage),
+		% we know that Random >= 0, so it's safe to use rem
+		% rather than mod, and rem is typically more efficient
+		Index = Random rem I,
+		array__lookup(Record0, Index, Next),
+		array__lookup(Record0, I1, MaxImage),
 		Order1 = [Next | Order0],
-		map__det_update(Record0, Index, MaxImage, Record1),
-		map__det_update(Record1, I1, Next, Record2),
+		array__set(Record0, Index, MaxImage, Record1),
+		array__set(Record1, I1, Next, Record2),
 		perform_sampling(I1, Record2, Order1, Order, RS1, RS)
 	).
 

-- 
Fergus Henderson <fjh at cs.mu.oz.au>  |  "I have always known that the pursuit
WWW: <http://www.cs.mu.oz.au/~fjh>  |  of excellence is a lethal habit"
PGP: finger fjh at 128.250.37.3        |     -- the last words of T. S. Garp.
--------------------------------------------------------------------------
mercury-developers mailing list
Post messages to:       mercury-developers at cs.mu.oz.au
Administrative Queries: owner-mercury-developers at cs.mu.oz.au
Subscriptions:          mercury-developers-request at cs.mu.oz.au
--------------------------------------------------------------------------



More information about the developers mailing list