@@ -1401,6 +1401,8 @@ shuffle_s(List, {#{max:=_, next:=Next} = AlgHandler, R0})
14011401% %
14021402% % The `random_bit()` can be generated with small overhead by generating
14031403% % a random word and cache it, then shift out one bit at the time.
1404+ % %
1405+ % % Also, it is faster to do a 4-way split instead of a 2-way.
14041406
14051407% % Leaf cases - random permutations for 0..4 elements
14061408shuffle_r ([], Acc , P , S ) ->
@@ -1416,25 +1418,28 @@ shuffle_r([X, Y, Z, Q], Acc, P, S) ->
14161418% % General case - split and recursive shuffle
14171419shuffle_r ([_ , _ , _ , _ | _ ] = List , Acc , P , S ) ->
14181420 % % P and S is bitstream cache and state
1419- shuffle_r (List , Acc , P , S , [], []).
1421+ shuffle_r (List , Acc , P , S , [], [], [], [] ).
14201422% %
1421- % % Split L into two random subsets: Zero and One
1423+ % % Split L into 4 random subsets
14221424% %
1423- shuffle_r ([], Acc0 , P0 , S0 , Zero , One ) ->
1424- % % Split done, recursively shuffle Zero and One onto Acc
1425+ shuffle_r ([], Acc0 , P0 , S0 , Zero , One , Two , Three ) ->
1426+ % % Split done, recursively shuffle the splitted lists onto Acc
14251427 {Acc1 , P1 , S1 } = shuffle_r (Zero , Acc0 , P0 , S0 ),
1426- shuffle_r (One , Acc1 , P1 , S1 );
1427- shuffle_r ([X | L ], Acc , P , S , Zero , One )
1428- when is_integer (P ), 1 < P , P < 1 bsl 57 ->
1429- case P band 1 of
1430- 0 ->
1431- shuffle_r (L , Acc , P bsr 1 , S , [X | Zero ], One );
1432- 1 ->
1433- shuffle_r (L , Acc , P bsr 1 , S , Zero , [X | One ])
1428+ {Acc2 , P2 , S2 } = shuffle_r (One , Acc1 , P1 , S1 ),
1429+ {Acc3 , P3 , S3 } = shuffle_r (Two , Acc2 , P2 , S2 ),
1430+ shuffle_r (Three , Acc3 , P3 , S3 );
1431+ shuffle_r ([X | L ], Acc , P0 , S , Zero , One , Two , Three )
1432+ when is_integer (P0 ), 3 < P0 , P0 < 1 bsl 57 ->
1433+ P1 = P0 bsr 2 ,
1434+ case P0 band 3 of
1435+ 0 -> shuffle_r (L , Acc , P1 , S , [X | Zero ], One , Two , Three );
1436+ 1 -> shuffle_r (L , Acc , P1 , S , Zero , [X | One ], Two , Three );
1437+ 2 -> shuffle_r (L , Acc , P1 , S , Zero , One , [X | Two ], Three );
1438+ 3 -> shuffle_r (L , Acc , P1 , S , Zero , One , Two , [X | Three ])
14341439 end ;
1435- shuffle_r ([_ | _ ] = L , Acc , _P , S0 , Zero , One ) ->
1440+ shuffle_r ([_ | _ ] = L , Acc , _P , S0 , Zero , One , Two , Three ) ->
14361441 [P |S1 ] = shuffle_new_bits (S0 ),
1437- shuffle_r (L , Acc , P , S1 , Zero , One ).
1442+ shuffle_r (L , Acc , P , S1 , Zero , One , Two , Three ).
14381443
14391444% % Permute 2 elements
14401445shuffle_r_2 (X , Acc , P , S , Y )
0 commit comments