in reply to RE (tilly) 1: Fisher-Yates Shuffle
in thread Fisher-Yates Shuffle
But I think your log(n) time is wrong. Consider the fact that each pass through the loop is dealing with a smaller array. (Speaking of which, I ought to have used a pre-decrement instead of a post decrement... the last pass is a waste of time.) So the value of the branch decreases as the size of the array increases, right? Think about it this way: The odds of branching on the first pass through an array of size N are 1/N. The next passs through, the relative array size is N-1. So for any given array of size N the odds of branching at all are between 1 and 1/N * 1/(N-1) * 1/(N-2) and so on. That makes the high end, where every single loop branched, equal to 1/(N!). The worst case scenario of branching often gets pretty rare pretty quick. That branch gets pretty useless pretty fast, no?
So what's the penalty of having the branch? Well the compiler can do one of two things with the assembly code. One, it guesses that the branch is common - and arranges the assembly to jump to a different memory block when the two indexes arn't equal. So you pay the price of doing that test and jumping pretty often... not good. OR The compiler guesses that the branch is rare... and has to test for equivalence on every pass and you paying the price. (This is more likely what Perl did, considering how close the benchmarks were.) Note that the test itself is simple. Its just a pass through an AND gate and maybe a NOT gate. (There is a third, even uglier, possability... that Perl actually uses a cache guess strategy where it guesses that if it branched last time then it will branch again... and vice-versa. This is a good strategy when the odds are closer to 50-50, but not in this case.)
But if you don't introduce the branch at all, you pay a different penalty... which is why I posted this Meditation in the first place: Now you have removed the test for equivalence on every pass, and removed two lines of assembly code, but you are also trying to swap an array element with itself. If there were no penalty for that then the branch would never make sense, but I doubt this very much. So the question is... how severe is the penalty? Is it worse then checking if two 32 bit ints are equal? Probably. But not much. And since its more likely that you'll have to do the swap anyway... you might as well, right?
|
---|
Replies are listed 'Best First'. | |
---|---|
RE (tilly) 3: Fisher-Yates Shuffle
by tilly (Archbishop) on Aug 30, 2000 at 06:51 UTC | |
by Adam (Vicar) on Aug 30, 2000 at 07:29 UTC | |
by BlaisePascal (Monk) on Aug 30, 2000 at 07:58 UTC | |
by tilly (Archbishop) on Aug 30, 2000 at 14:48 UTC | |
by tilly (Archbishop) on Aug 30, 2000 at 07:51 UTC | |
by tilly (Archbishop) on Aug 30, 2000 at 14:45 UTC | |
by Adam (Vicar) on Aug 30, 2000 at 20:45 UTC | |
by tilly (Archbishop) on Aug 30, 2000 at 21:09 UTC |