Profaitchikenz Haiku Posted July 15, 2020 Share Posted July 15, 2020 (edited) 2 hours ago, Wulfie Reanimator said: A string that begins with "0x" will be interpreted as a hexadecimal number, it will keep reading the number until a character other than 0-9 and A-F is encountered. Ah ha, so it's the "-" in the key that causes conversion to cease without there being any overflow. Neat. Qie was right then about it being no coincidence the first 32 bits are a distinct chunk? Edited July 15, 2020 by Profaitchikenz Haiku Link to comment Share on other sites More sharing options...
Wulfie Reanimator Posted July 15, 2020 Share Posted July 15, 2020 (edited) 3 hours ago, Profaitchikenz Haiku said: Ah ha, so it's the "-" in the key that causes conversion to cease without there being any overflow. Neat. Qie was right then about it being no coincidence the first 32 bits are a distinct chunk? Yes and no. It's not a coincidence.. in the sense that UUIDs are a general standard used in a lot of places, not just Second Life, so the Lindens did not come up with UUIDs with this in mind. But at the same time.. the fact that they chose this system is a happy coincidence/convenience that just happens to allow this kind of neat conversion (and maybe that's a contributing reason they chose it, but I doubt it). Even the way strings are interpreted as numbers is something seen in C/C++, so that's not specific to SL either. Edited July 15, 2020 by Wulfie Reanimator 2 Link to comment Share on other sites More sharing options...
Kyrah Abattoir Posted August 12, 2020 Share Posted August 12, 2020 On 2/25/2020 at 12:27 PM, CoffeeDujour said: Really have to be careful when using tools designed to make LSL mimic a bigger more connected language, very easy to end up with a large slow script that if hand optimized would be a fraction of the size and much faster. Agreed, unfortunately as scripts grow in size and complexity, it becomes difficult to keep one's sanity without some QoL features. 1 Link to comment Share on other sites More sharing options...
KT Kingsley Posted September 24, 2020 Share Posted September 24, 2020 (edited) If you use the LSL preprocessor in Firestorm you may be able to find copies of lost scripts in the Firestorm cache lslpreproc folder. (This tip courtesy of @Chaser Zaks.) Edited September 24, 2020 by KT Kingsley Link to comment Share on other sites More sharing options...
Quistess Alpha Posted February 27, 2022 Share Posted February 27, 2022 If you want to add more prims to an object, it's not too hard to rez them and then llCreateLink. But what if you want to delete a prim from your linkset? It was a nice 'ah-hah' moment when I realized that rather than having a die script in every prim that might need to be deleted, or trying to llRemoteLoadScriptPin() you can just set them to temporary and move them out of the way: integer addremove; delete_link(integer n) { llSetLinkPrimitiveParamsFast(n, [ PRIM_POS_LOCAL,<0,0,-1>, // out of the way. PRIM_TEMP_ON_REZ, TRUE, // set to delete // setting for one prim seems to set for the whole linkset. PRIM_COLOR,ALL_SIDES,<0,0,0>,0.0 // invisible. ]); llBreakLink(n); llSetLinkPrimitiveParamsFast(llGetNumberOfPrims()!=1, // when there is only 1 prim, the root has link# 0, Ugh. [ PRIM_TEMP_ON_REZ, FALSE]); } default { state_entry() { llRequestPermissions(llGetOwner(),PERMISSION_CHANGE_LINKS); } touch_start(integer total_number) { addremove=!addremove; if(addremove) { llRezAtRoot(llGetInventoryName(INVENTORY_OBJECT,0),llGetPos()+<0,0,1>,<0,0,0>,<0,0,0,1>,0); }else { delete_link(2); // should do a permissions check. } } object_rez(key ID) { llCreateLink(ID,TRUE); // should do a permissions check. } } 3 Link to comment Share on other sites More sharing options...
Mollymews Posted March 23, 2022 Share Posted March 23, 2022 (edited) i will pop this in here as it comes up enough times to warrant doing so often we need to keep a value within some lower (min) and upper (max) bounds. The textbook code to do this is typically if (n < min) n = min; else if (n > max) n = max; // else (n >= min && n <= max) // n = n; when we need to do this more than one time in our script then we often wrap this in a function, similar too integer bounds(integer n, integer min, integer max) { if (n < min) return min; if (n > max) return max; return n; } // usage n = bounds(n, min, max); a alternative to a user-defined function, is a list lookup where the expression evaluates to a index in the set [0, 1, -1] n = llList2Integer([min, n, max], (n > min) * (-(n > max) | 1)); which saves us about 500 memory bytes that a user-defined function incurs Edited March 23, 2022 by Mollymews typo 5 Link to comment Share on other sites More sharing options...
Quistess Alpha Posted July 2, 2022 Share Posted July 2, 2022 (edited) On 3/22/2022 at 8:43 PM, Mollymews said: often we need to keep a value within some lower (min) and upper (max) bounds. I had a think about this again, and ended up with a slightly more efficient answer: If our lower bound is 0, we can be really efficient: x *= (x>0); // if (x < 0) x=0; this can be generalized by adding and subtracting a constant from x: x = c+((x-c)*(x>c)); // if(x<c) x=c; for upper bounds, we get a very similar looking answer by subtracting x from a constant: (N.B. (c-(c-x))==x) x = c-((c-x)*(x<c)); // if(x>c) x=c; //ETA: this is actually equivalent to: x = c+((x-c)*(x<c)); //e.g. upper and lower bounds are identical save for the conditional. a bit of a brain teaser to work through. Note that the conditions represent when x=x, which is the opposite of the "textbook" conditional of when to set x to the boundary. ETA: Threading those together and re-arranging a bit leads to: x = (x>l)*((x<u)*(x-u)+(u-l))+l; // if(x<l) x=l; if(x>u) x=u; // example: x = (x>3)*((x<5)*(x-5)+2)+3; Edited July 3, 2022 by Quistess Alpha 1 2 Link to comment Share on other sites More sharing options...
Quistess Alpha Posted July 2, 2022 Share Posted July 2, 2022 (edited) Also, as I think @Mollymews tested at one point, inline list construction is quite inefficient. Instead of Value = llList2Float([a,b,c,d],i); consider using Value = (a*(i==0))+(b*(i==1))+(c*(i==2))+(d*(i==3)); if a,b,c,d are integers, floats or vectors, and aren't already in a list, but ~are calculated right before you select one. (If it makes sense to have the list as a global variable that is never or rarely modified, then llList2* might be as or more efficient) Applying that to the previous post, we get: integer x /*= ...*/; // clamp x to be max if x>max, and min if x<min { // brackets can be used to isolate the scope of a 'working variable'. In this case, we only need i for this calculation. integer i = (x>max)-(x<min); x = (min*(i==-1)) + (x*(i==0)) + (max*(i==1)); } Edited July 2, 2022 by Quistess Alpha 'i' can be an index rather than a bitmask, saving a few cycles. 2 1 Link to comment Share on other sites More sharing options...
Mollymews Posted July 3, 2022 Share Posted July 3, 2022 14 hours ago, Quistess Alpha said: Also, as I think @Mollymews tested at one point, inline list construction is quite inefficient about inline lists, was Qie prompted by Wulfie who showed that a var list is significantly more performant than a const list they showed that is best to go with a var list as an parameter for llList2... rather than a const list // do this list args = ["No", "Yes"]; string result = llList2String(args, condition); // where condition is TRUE or FALSE // and not string result = llList2String(["No", "Yes"], condition); // where condition is TRUE or FALSE. 14 hours ago, Quistess Alpha said: integer x /*= ...*/; // clamp x to be max if x>max, and min if x<min { // brackets can be used to isolate the scope of a 'working variable'. In this case, we only need i for this calculation. integer i = (x>max)-(x<min); x = (min*(i==-1)) + (x*(i==0)) + (max*(i==1)); } i really really like this about the only thing I could add to it is that when we compare a variable to a const in LSL Mono then is a bit more performant to place the const on the left. Whyam not exactly sure, something something stack handling x = (min * (-1 == i)) + ( x * (0 == i)) + (max * (1 == i)); 1 Link to comment Share on other sites More sharing options...
Quistess Alpha Posted July 3, 2022 Share Posted July 3, 2022 13 minutes ago, Mollymews said: is a bit more performant to place the const on the left. I've also heard it's better for catching = vs == mistakes: -1=i; is not a valid statement. As for above code and miniscule improvements, I've been mulling over x = (x>l)*((x<u)*(x-u)+(u-l))+l; // if(x<l) x=l; if(x>u) x=u; and although a bit confusing, the general pattern allows for checks (if) and default (else{ }), and is about as efficient as possible: // normally would write: if(!cA) return rA; else if(!cB) return rB; else if(!cC) return rC; else if(!cD) return rD; else return rE; // can instead try: (cA)* ((cB)* ((cC)* ((cD)* ( (rE-rD) )+(rD-rC) )+(rC-rB) )+(rB-rA) )+rA; If the return values rA, rB etc. are constants, the difference can be done in-code. (cA)*((cB)*((cC)*(W)+X)+Y)+Z; // if(!cA) return Z; if(!cB) return Y+Z; if(!cC) return X+Y+Z; else return W+X+Y+Z; Compare (x>3)*((x<5)*(x-5)+2)+3; 2 comparisons, 2 multiplications, 1 difference, 2 sums. with { integer i = (x>5)-(x<3); x = (-1==i)*3 + (!i)*x + (1==i)*5; } 5 comparisons, 3 multiplications, 1 difference, 2 sums. . . . but maybe this discussion would be best for an efficiency/ optimization thread . . . 2 Link to comment Share on other sites More sharing options...
Mollymews Posted July 3, 2022 Share Posted July 3, 2022 (edited) 8 hours ago, Quistess Alpha said: maybe this discussion would be best for an efficiency/ optimization thread . . . is probably better to start a new thread yes this thread is more for quick tips/statements rather than a general discussion on inlining code inline code is a large topic and quite varied, and the question to do or not do is often circumstantial. I think is worth having these more indepth discussion in its own thread, about the various methods and techniques that can optimise when we do inline code and much of what we are currently discussing also touches on logic programming. So the discussion we can also have in its own thread can be about about how and where we can use logic programming methods to achieve some measurable gain for our scripts, be that in execution speed or memory savings ps. Repost your last in a new thread as is quite interesting. Is also a thing about using equality vs logical operators which is also worth talking about Edited July 3, 2022 by Mollymews typs Link to comment Share on other sites More sharing options...
primerib1 Posted December 5, 2022 Share Posted December 5, 2022 Is it okay if I create a post in this forum for the express purpose of asking for Code Review? I don't think LSL is 'mainstream' enough for me to post in codereview.stackexchange.com ... 1 Link to comment Share on other sites More sharing options...
Love Zhaoying Posted December 5, 2022 Share Posted December 5, 2022 On 7/3/2022 at 7:51 AM, Quistess Alpha said: I've also heard it's better for catching = vs == mistakes: -1=i; is not a valid statement. As for above code and miniscule improvements, I've been mulling over x = (x>l)*((x<u)*(x-u)+(u-l))+l; // if(x<l) x=l; if(x>u) x=u; and although a bit confusing, the general pattern allows for checks (if) and default (else{ }), and is about as efficient as possible: // normally would write: if(!cA) return rA; else if(!cB) return rB; else if(!cC) return rC; else if(!cD) return rD; else return rE; // can instead try: (cA)* ((cB)* ((cC)* ((cD)* ( (rE-rD) )+(rD-rC) )+(rC-rB) )+(rB-rA) )+rA; If the return values rA, rB etc. are constants, the difference can be done in-code. (cA)*((cB)*((cC)*(W)+X)+Y)+Z; // if(!cA) return Z; if(!cB) return Y+Z; if(!cC) return X+Y+Z; else return W+X+Y+Z; Compare (x>3)*((x<5)*(x-5)+2)+3; 2 comparisons, 2 multiplications, 1 difference, 2 sums. with { integer i = (x>5)-(x<3); x = (-1==i)*3 + (!i)*x + (1==i)*5; } 5 comparisons, 3 multiplications, 1 difference, 2 sums. . . . but maybe this discussion would be best for an efficiency/ optimization thread . . . I am curious if the condensed form is actually any "faster", or just takes less bytecode. 1 Link to comment Share on other sites More sharing options...
Wulfie Reanimator Posted December 5, 2022 Share Posted December 5, 2022 12 hours ago, primerib1 said: Is it okay if I create a post in this forum for the express purpose of asking for Code Review? I don't think LSL is 'mainstream' enough for me to post in codereview.stackexchange.com ... It should be totally fine. 2 1 Link to comment Share on other sites More sharing options...
primerib1 Posted January 21 Share Posted January 21 A very important tip I learnt in a (tangentially related) discussion about LSD: Trigger GC using llSleep() to ensure release of "lingering objects". Very important if your script keeps building temporary gigantic lists and/or strings. Link to comment Share on other sites More sharing options...
Recommended Posts
Please sign in to comment
You will be able to leave a comment after signing in
Sign In Now