Array shuffle function not touching last element - actionscript-3

I am using this function to shuffle a 4 element array. It shuffles the first 3 elements well, shuffling them randomly, but the last element is only sometimes shuffled around with the other three.
public function shuffleArray(objA:Object, objB:Object):int{
return Math.round(Math.random() * 2) - 1;
}

There's nothing really wrong with it. That's random. As mentioned, the algorithm used for Math.random() makes the difference and I don't believe the AS3 algorithm is especially good.
For testing purposes, I ran it a few times in JS and saw very similar things, where a specific index was the same quite a few times in a row. My results were showing 5-10 times in a row, the one of the indexes would be exactly the same. In a few tests, I saw the exact same result appear 11 times in a row. Running it with a higher maxValue (I tried 15) resulted in a much more random outcome, though it still had the same problems. Interestingly, bumping the iterations up seemed to break the pattern. I noticed it became slightly more random as we got higher in tries (I tried 10k).
var maxValue = 4,
iterations = 100,
a = [];
for (var i = 1; i <= maxValue; i++) {
a.push(i);
}
function shuffle(a, b) {
return Math.round(Math.random() * 2) - 1;
}
for (var i = 0; i < iterations; i++) {
console.log(a.sort(shuffle));
}
http://jsfiddle.net/KA2tf/1/
I did test the same code in Flash (with some minor alterations for AS3, obviously) and saw mostly similar results (to be expected; I believe Flash and JS use very similar algorithms, if not the same one). There's only 24 different combinations a 4 item array can be sorted. You're bound to get repetition.

Related

Actionscript, improving xor performance?

I am using the below code to process some large files.
var joinedBytes:ByteArray = new ByteArray;
joinedBytes.length = _chunkSize;
for (var i:Number = 0; i < _chunkSize; i++) {
joinedBytes.writeByte(_xorBytesBuffer[i]^_rndBytesBuffer[i]);
}
Its taking about 2.5 seconds to process 10mb of data on a desktop.
Is this normal performance?
Does any way exist to speed it up?
I think that some of the time is writing to the byte array.
EDIT:
_xorBytesBuffer and _rndBytesBuffer are both byte arrays.
I didn't test everything. I could be wrong somewhere below but...
ByteArray is faster
The [i] suggest you are using Vector/Array using another ByteArray for _xorBytesBuffer and _rndBytesBuffer should speed things up.
You want also operate on larger data i.e. writeUnsignedInt() instead of writeByte()
See also this question
uint is faster vs Number
And if you only have 10MB, you would like to use var i:uint instead of Number.
Another thing is you can replace i++ wit ++i though I did't really test if this has much impact - I only heard that it's faster.
Remove additional steps.
You could even try something like:
for (var i:uint = 0; i < _chunkSize;) {
joinedBytes.writeByte(_xorBytesBuffer[i]^_rndBytesBuffer[i++]);
}
Please let us know it _rndBytesBuffer[i++] makes any difference ;)
Wait, I just said to not use indicies but another ByteArrays... Well If you still want to try above still let us know how it performs ;)
Make sure your condition check is as simple as possible.
Make sure you have something like var _chunkSize:uint instead of
function _chunkSize(){return something;}

Octave use of iteration (start:step:end)

Let's say I have an array A = [1 2 3 4 5 6 7 8 9 10]. I want to iterate through it and do something with each number.
A(start:step:end) -> since I want to iterate with step 1 I use A(1:10).
Question here is, how can I use that iteration? In C++ you would do
for (int i = 0; i < 10; i++)
{
//DO SOMETHING
}
I've spent 4 hours searching how to use that iteration. I have not found a single explanation to such a trivial thing: passing block of code to actually do something with numbers. Don't even know how to use current index (i.e., i in C++).
I have my function in Octave f = #(variable) (...), however when I call f(A(1:10)) it is not really passing each number to the function but rather finishes iteration and then executes function.
I'd expect something like
A(1:10) (DO SOMETHING WITH EACH NUMBER)
or in my example
A(1:10) ( f(INDEX) )
but that does not seem to work either.
I know Octave has a built-in for loop but in my case it is too slow.
That was simplified explanation, here is more advanced.
I want to multiply matrix A in such way that one matrix starts iteration with 1 and the other one with 2 (e.g., A(1:end-1).*A(2:end)) and use each multiplied number in my custom function.
An analogue of C++ loop
for (int i = 0; i < 10; i++)
{
//DO SOMETHING
}
would be
for i = 1:10
//DO SOMETHING
end
since Octave indices are 1-based.
There is no array.forEach(do something) construction in Octave.
Most of the time, a speed-up is achieved by passing arrays (vectors and matrices) to a function at once, and structuring the function itself so that it can handle an array. How to do the latter depends on what the function is.

Pros and Cons of i != n vs i < n in an int for loop

What are the pros and cons of using one or the other iteration functions ?
function (int n) {
for (int i = 1; i != n; ++i) { ... }
}
vs
function (int n) {
for (int i = 1; i < n; i++) { ... }
}
I think the main argument against the first version is that it is a much less common idiom.
Remembering that code is read more often than it is written, it does not make sense to use a less familiar form of for loop if there isn't a very clear advantage to doing so. All it achieves is distracting anyone working on the code in future.
So primarily for code maintenance reasons (by others as well as the original coder) I would favour the more common second format.
The version with < will work correctly if n is less than 1. The version with != will go into an infinite loop (well, probably not infinite, as integer variables wrap around in most languages).
Using < also generalizes better. E.g.
for (i = start; i < end; i += increment)
This will work even if end - start is not a multiple of increment.
The first one is quite dangerous and could cause an infinite loop.
If n is ever less than 1, the loop will never exit.
Also if something changes i inside the loop, so that it skips the value of n, then again the loop will never exit.
Edit: OK to be more precise when I say never exit, it will ultimately exit one way or another, but it won't be in the manner most sane developers expect. I can just imagine the look on the poor guy that debugs your code that calls the database 2 billion times.

Possibility of flash Math.random() returning 1

We all know good old Math.random(). It returns a random floating point number between 0 and 1.
What I can't seem to find any evidence about is if zero or one is exclusive or inclusive.
I know that if they are inclusive, the probability of hitting either one of these values is seriously low.
But I can't help but wonder if I should wasting an if statement looking for it or not.
In my current scenario zero is not a problem, but one is.
var __rand:uint = Math.floor( Math.random() * myArray.length );
var result:String = myArray[__rand];
if the 1 in Math.random() is exclusive, then I will know that will NEVER be 1, and therefore __rand could never equal myArray.length and should always be below it.. But just wasn't sure if I should waste time in some performance critical code if I should account for it.
PS: The code above is NOT the performance critical code, just an example
Basically, just 2 simple questions.
1) Is returning one impossible or possible.
2) If possible, is it worth accounting for it.
As per the docs:
Returns a pseudo-random number n, where 0 <= n < 1. The number
returned is calculated in an undisclosed manner, and is
"pseudo-random" because the calculation inevitably contains some
element of non-randomness.
So it can be 0 but not 1. You don't have to worry about index out of bounds.
By the way, if this was really performance critical code, you are better off casting the value as int or uint rather than using Math.floor (see this performance test).
Math.random will return a number between 0 and (1 exclusive). Never will return a 1.

Running AS3 Function Asynchronously

I'm having a bit of trouble making sense of some of the tutorials for this online, thus why I'm asking here. (Using ActionScript 3, Adobe AIR, and Flash Professional CS5.5)
I have a very heavy function in my AS3 document class that I need to run asynchronously, so it doesn't stop the code on the MovieClip itself (don't ask me why, it just needs to be that way.)
So, simply put, how do I run this document class function (StartNow) asynchronously? The code can be placed in the document class or on the movieclip, I don't care where. It seems to be a relatively simple and common practice, but all my research is digging up nothing.
Thanks!
If your target is Flash player 11.4, there are Worker objects which can be assigned such a heavy function. I had no FP11, and eventually made a procedural generator that lasted more than 300 seconds per iteration in total. I had to use a state-based approach, paired with an enter frame listener. In my c ase, the entire complex generation process was split into logical chunks that were small enough to be completed within a reasonable timespan, and had a variable tracking the current generation phase. So, when another frame called the generation function, it read last completed step from that variable, performed one extra step with its set of data, stored the new value and exited for the frame. This, as is, is not a pure asynchronous process, but a pseudo-multitasking approach, this can suit you if your function that makes your SWF lag is splittable.
In Flash there is no such thing as run a function asynchronously, you have to do it yourself, unless you want to use Workers (like Vesper said). Workers gives you a separate process. Otherwise, you have to break your calculation into parts. This is how you do it:
Imaging 'trace' is a very heavy operation. It's not, but just to illustrate. This simple for-loop is runned on a frame, and causes a lower framerate, since it's all calculated before the frame actually renders.
for(var i:int = 0; i < 1000; i ++)
{
trace(i); // heavy calculation here
}
So you have to break the calculation into parts, and break it to be able to run the calculation over time.
To do that, you have to create a function which just takes a part of the loop every time:
calculatePart(0, 1000, 20);
function calculatePart(startIndex:int, endIndex:int, amountPerRun:int)
{
for(var i:int = startIndex; (i < startIndex + amountPerRun) || (i < endIndex); i ++)
{
trace(i); // heavy calculation here
}
if (i < endIndex)
{
calculatePart(i, endIndex, amountPerRun);
}
}
This is actually the same function as the simple for-loop in the first code, it also outputs 1000 traces. It is prepared to run in parts, but this isn't async yet. We can now change the function easily, so the function operates over time.
I use the setTimeout for this. You can also use a ENTER_FRAME event-listener or the Timer class for this, but for the sake of this example I try to keep it clear.
calculatePart(0, 1000, 20, 100);
function calculatePart(startIndex:int, endIndex:int, amountPerRun:int, timeBeforeNextRun:Number)
{
for(var i:int = startIndex; (i < startIndex + amountPerRun) && (i < endIndex); i ++)
{
trace(i); // heavy calculation here
}
if (i < endIndex)
{
setTimeout(calculatePart, timeBeforeNextRun, i, endIndex, amountPerRun, timeBeforeNextRun);
}
}
As you can see, I've added a timeBeforeNextRun parameter. If you run the example, you can see it takes 100 milliseconds before 20 traces are outputted.
If you set it very low, the calculation will be tried to be done very fast, however you cannot gain extra speed just by trying to do more in less time of course. You have to play with the time and amount variables, you can test which one actually gives better performance (or less lag).
// more time between a run, less calculations per run
calculatePart(0, 1000, 30, 10);
// more calculations per run, more time between a run
calculatePart(0, 1000, 100, 30);
Hope this helps.
If you want to use a smarter calculation of the time, I found this utility class very helpful, which measures how much time the calculation actually took, and alter the time itself.