I ran a test just now:
function overflow(stack:int = 0):void
{
if(stack < 5290)
{
trace(stack);
overflow(stack + 1);
}
}
overflow();
This always throws a StackOverflow error after 5287
calls.
Error #1023: Stack overflow occurred.
Is this limit variable (depending on machine specs, environment, etc) or is that a flat value defined somewhere? If I change the if
statement to less than 5287, I don't get the error.
Obviously it's variable. Since all the calculations you really do are located in stack (disassembly report codes show pushbyte
instructions and other stuff that's working with stack, as non-operand arithmetics), this value only reports how many function contexts can be put into the stack until it overflows.
I have decided to run some tests for recursion thresholds as based on this article that was referenced in baris's comment. The results were pretty embarrassing. Test environment: FlashDevelop 3.3.4 RTM, Flash player debugger 10.1.53.64, flash compile mode: release. "Debug" mode didn't change numbers cardinally, checked that too.
Locals number Iterations (static int) Iterations (Math.random())
0 5306
1 4864 4856
2 4850 4471
3 4474 4149
4 4153 3870
5 3871 3868
6 3869 3621
7 3620 3404
8 3403 3217
9 3210 3214
10 3214 3042
11 3042 3045
10 mixed 3042 1 value was assigned Math.random() and 9 - static int
10 advancedRandom 2890 1 value was assigned a custom random with 1 parameter
Note, all of these values vary within a margin of ten between subsequent executions. The "static int" and "Math.random()" are designations of what is assigned to locals wihin the recursively called function. This, however, leads me to assume the following:
Hm, this is interesting. I took a look at the link that Barış gave. It seems like it might be to be with 'method complexity' after all, but I am not sure how to further test it. I am using Flash CS5, publishing for Flash Player 10, Actionscript 3 (of course).
Original:
function overflow(stack:int = 0):void {
if(stack < 5290){
trace(stack);
overflow(stack + 1);
}
}
// gives 5287
Now adding a single Math.random() call to the overflow() method:
function overflow(stack:int = 0):void {
Math.random();
if(stack < 5290){
trace(stack);
overflow(stack + 1);
}
}
// gives 4837
Adding multiple Math.random() calls make no difference, nor does storing it in a local variable or adding another parameter to the overflow() method to 'carry' that random generated value
function overflow(stack:int = 0):void {
Math.random();
Math.random();
if(stack < 5290){
trace(stack);
overflow(stack + 1);
}
}
// still gives 4837
At this point I tried different Math calls, such as:
// just the change to that 1 line:
Math.pow() // gives 4457
Math.random(), Math.sqrt(), Math.tan(), Math.log() // gives 4837
Interestingly, it doesn't seem to matter what you pass in to the Math class, but it remains constant:
Math.sqrt(5) vs Math.sqrt(Math.random()) // gives 4837
Math.tan(5) vs Math.tan(Math.random()) // gives 4837
Math.pow(5, 7) vs Math.pow(Math.random(), Math.random()) // 4457
Until I chained 3 of them:
Math.tan(Math.log(Math.random())); // gives 4457
It looks like two Math calls from that 'group' is "equal" to one Math.pow() call? =b Mixing Math.pow() and something else doesn't seem to decrease the value though:
Math.pow(Math.random(), Math.random()); // gives 4457
However, chaining two Math.pow()'s:
Math.pow(Math.pow(Math.random(), Math.random()), Math.random()); // 4133
I could go on and on, but I wonder if there is some pattern:
Results: 5287, 4837, 4457, 4133
Differences: 450 380 324
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With