Search the Community
Showing results for tags 'mono'.
-
Hi Linden people ? 1- SUMMARY I have performed a memory benchmark on LSL Mono scripts (see below for details). It shows that on average, for each global variable of type integer, more than 22 bytes are consumed from the script memory. 22 bytes is a lot, compared to the actual integer payload (4 bytes). Considering that LSL Mono scripts have only 64K bytes available, it would be nice to spare them... - What accounts for the 20+ bytes per integer? - Is there a way to reduce this memory consumption ? 2- BENCHMARK CODE The benchmark is very simple : integer i1; integer i2; integer i3; ... integer i<N-1>; integer i<N>; default { state_entry() { llOwnerSay((string) llGetFreeMemory()); } } 3- BENCHMARK RESULTS N llGetFreeMemory() Comments 0 62172 1 62164 2 bytes for integer i 2 62164 0 byte for i2 3 62156 2 bytes for i3 4 62156 0 byte for i4 5 62148 8 bytes for i5 6 62148 0 byte for i6 ... 10 62132 11 61612 520 BYTES FOR i11!!! 12 61612 0 byte for i12 13 61604 8 bytes for i13 14 61604 0 byte for i14 15 61596 8 bytes for i15 16 61596 ... 17 61588 18 61588 ... 38 61508 39 61508 40 60988 512 BYTES FOR i40!!! ... 1000 40252 21.9 byte average per integer 2000 17308 22.4 byte average per integer 2742 4 22.7 byte average per integer 2743 heap stack collision 4- TENTATIVE ANALYSIS Because global variables have to be re-initialized on script reset, I suspect Mono keeps a copy of the initial value in memory. This would account for 8 bytes per integer. The fact that free memory decreases by about 512 bytes with integers i11 and i40 (in the benchmark) suggests that i11 and i40 have resulted in an increase of the script's code size (in SL LSL, memory for code increases by chuncks of 512 bytes). Thus I suspect that for each global variable, in addition to the above-mentioned 8 bytes, the Mono compiler adds code to the script, to re-initialize the value of the variable on script reset. Still, 22 bytes per integer is an awful lot. For example, for un-assigned global integers (such as in the benchmark code), a simple loop assigning value 0 should suffice. Suggestions, anybody?
-
It would be useful to have an open source benchmark for scripts in SL. Something that could be rezzed / worn, run through a few tests and then give results that can be meaningfully compared over time and to other regions. It must be able to give a consistent result over sequential runs in the same location assuming nothing else changes. Is this even possible? What should be tested and how? What results should be generated? What should be done with the data? Thoughts, ideas, code to test ?
-
So a little while back, while the forums were offline for the new site update, I had a question I wanted answered: what loops are fastest in mono, and what stipulations should be taken into account when scripting them? As it turns out, this is quite an interesting topic that has a lot of commentators scratching their heads. Well, I'm not here to talk about efficiency, but I am here to definitively conclude which loops appear to be fastest (and when they usually are). Using a simple script that can be found below, I conducted some tests (in mono) to see what loops finish fastest with no arguments inside of them to test the true speed of the loop itself, from a practical approach without considering the theory behind it. My results could be considered a little odd, as the answer of 'fastest' actually appears to vary based on how many iterations you happen to be looping through. The results of my particular test are printed below, as concluded by the script found at the end of the page: 'for' loop time to 100: 0.000000 'for' loop time to 1,000: 0.024513 'for' loop time to 10,000: 0.044505 'for' loop time to 100,000: 0.596119 'for' loop time to 1,000,000: 6.318980 'do-while' loop time to 100: 0.000000 'do-while' loop time to 1,000: 0.030374 'do-while' loop time to 10,000: 0.114235 'do-while' loop time to 100,000: 1.198419 'do-while' loop time to 1,000,000: 12.739420 'while' loop time to 100: 0.000000 'while' loop time to 1,000: 0.014845 'while' loop time to 10,000: 0.116710 'while' loop time to 100,000: 1.200627 'while' loop time to 1,000,000: 12.317580 loop time to 100: All loops evenly matched for practical purposes. loop time to 1,000: 'while' loops beats all; 0.015529 seconds faster than 'do-while', and 0.009268 seconds faster than 'for'. loop time to 10,000: 'for' loop beats all; 0.06973 seconds faster than 'do-while', and 0.072205 seconds faster than 'while'. loop time to 100,000: for loop beats all; 0.6023 seconds faster than 'do-while', and 0.604508 seconds faster than 'while'. loop time to 1,000,000: for loop beats all; 6.42044 seconds faster than 'do-while', and 5.9986 seconds faster than 'while'. In simple conclusion, loops are a funny business and they can vary based on many probably factors. Please use the script to do the experiment yourself, as learning is always a personal endeavour! I hope this was helpful at least to someone, and that it might lead to better scripting habits in the future for all. Have a good one! default { touch_start(integer total_number) { if(llDetectedKey(0) == llGetOwner()) { llOwnerSay("Beginning loop test.\n "); integer i = 0; llResetTime(); for(i; i < 100; i += 1){} llOwnerSay("'for' loop time to 100: "+(string)llGetTime()); i = 0; llResetTime(); for(i; i < 1000; i += 1){} llOwnerSay("'for' loop time to 1,000: "+(string)llGetTime()); i = 0; llResetTime(); for(i; i < 10000; i += 1){} llOwnerSay("'for' loop time to 10,000: "+(string)llGetTime()); i = 0; llResetTime(); for(i; i < 100000; i += 1){} llOwnerSay("'for' loop time to 100,000: "+(string)llGetTime()); i = 0; llResetTime(); for(i; i < 1000000; i += 1){} llOwnerSay("'for' loop time to 1,000,000: "+(string)llGetTime()+"\n "); //----------- llSleep(2.0); //----------- i = 0; llResetTime(); do{i += 1;} while(i < 100); llOwnerSay("'do-while' loop time to 100: "+(string)llGetTime()); i = 0; llResetTime(); do{i += 1;} while(i < 1000); llOwnerSay("'do-while' loop time to 1,000: "+(string)llGetTime()); i = 0; llResetTime(); do{i += 1;} while(i < 10000); llOwnerSay("'do-while' loop time to 10,000: "+(string)llGetTime()); i = 0; llResetTime(); do{i += 1;} while(i < 100000); llOwnerSay("'do-while' loop time to 100,000: "+(string)llGetTime()); i = 0; llResetTime(); do{i += 1;} while(i < 1000000); llOwnerSay("'do-while' loop time to 1,000,000: "+(string)llGetTime() + "\n "); //----------- llSleep(2.0); //----------- i = 0; llResetTime(); while(i < 100){i += 1;} llOwnerSay("'while' loop time to 100: "+(string)llGetTime()); i = 0; llResetTime(); while(i < 1000){i += 1;} llOwnerSay("'while' loop time to 1,000: "+(string)llGetTime()); i = 0; llResetTime(); while(i < 10000){i += 1;} llOwnerSay("'while' loop time to 10,000: "+(string)llGetTime()); i = 0; llResetTime(); while(i < 100000){i += 1;} llOwnerSay("'while' loop time to 100,000: "+(string)llGetTime()); i = 0; llResetTime(); while(i < 1000000){i += 1;} llOwnerSay("'while' loop time to 1,000,000: "+(string)llGetTime()); } } }