# User:Brattle Resident

## Converting a rotation to a value that can be sent to @setpos:

This function is designed for use in an attachment. It seems to work reliably in a visible attachment; I have some evidence it may not work properly from a HUD attachment. (Or that could be some other unrelated bug.)

<lsl>

```float getCurrentAngle() {
```

rotation myrot = llGetRootRotation(); // theoretically, returns av's rot float angle = llRot2Angle(myrot); vector axis = llRot2Axis(myrot); //OwnerSay("myrot=" + (string)myrot + "; angle=" + (string)angle + "; axis=" +(string)axis); // If axis.z == 1, angle is rotating north from east (E=0,N=PI/2,W=PI) // If axis.z == -1, angle is rotating south from east (E=0,S=PI/2,W=PI) // @setroot requires an angle that rotates east from north (N=0,E=PI/2,S=PI,W=3PI/2 or -PI/2) float newangle; if (axis.z < 0) { newangle = angle + PI_BY_TWO; } else { newangle = PI_BY_TWO - angle; } return newangle;

```}
```

</lsl>

So if you want to rotate the avatar by 90 degrees, you could do: <lsl>

```float angle = getCurrentAngle();
angle += PI_BY_TWO;
llOwnerSay("@setrot:" + (string)angle + "=force";
```

</lsl>

## Performance tests: Lists vs. JSON

Test performed on 7/11/2014 in a region with no other users, in an attachment, wearing few others. Region is running Second Life Server 14.06.20.291; Mainland/Homestead.

### LSL List Performance

#### Extract data from a list

• 0.09 ms: ix = llListFindList(lList1, [target]);
• 0.01 ms: ix = llGetListLength(lList2);
• 0.01 ms: target = llList2String(lList2, 0); // 25-item list of strings
• 0.01 ms: target = llList2String(lList2,12);
• 0.05 ms: target = llList2String(lList3, 0); // 14-item list of small integers
• 0.01 ms: ix = llList2Integer(lList3, 0);
• 0.01 ms: ix = (integer)llList2Integer(lList3, 0);
• 0.11 ms: ix = (integer)llList2String(lList3, 0);

#### Modify a list

• 0.26 ms: lList2 = llListReplaceList(lList2, ["new"], 0, 0);
• 0.25 ms: lList2 = llListReplaceList(lList2, ["new"], 12, 12);
• 0.38 ms: lList2 = lList1 + lList1 + lList1 + lList1 + lList1;
• 0.12 ms: lList3 = lList2 + "a";
• 0.16 lList3 = lList2 + ["a"];

• 0.004 ms: lList2 = lList1;
• 0.09 ms: lList2 = lList1; lList2 += "a";
• 0.15 ms: lList2 = lList1; lList2 += ["a"]
• 0.08 ms: lList2 = lList1; lList2 = lList1 + "a";
• 0.15 ms: lList2 = lList1; lList2 = lList1 + ["a"];
• 0.16 ms: lList2 = lList1; lList2 = ["a"] + lList1;
• 0.07 ms: lList2 = lList1; lList2 = "a" + lList1;

### LSL String Performance

#### Extract data from a string

• 0.74 ms : ix = llStringLength(jObject);
• 1.15 ms: ix = llSubStringIndex(jObject, "alpha");
• 1.17 ms: ix = llSubStringIndex(jObject, "silon");
• 1.20 ms: ix = llSubStringIndex(jObject, "absnt");
• 1.16 ms: json2 = llGetSubString(jObject, 0, 4);
• 1.19 ms: json2 = llGetSubString(jObject, 55, 59);
• 1.17 ms: json2 = llGetSubString(jObject, -7, -2);

#### Modify a string

• 1.85 ms: json2 = llDeleteSubString(jObject, 0, 4);
• 2.58 ms: json2 = json2 = llInsertString(jObject, 5, "newtx");

• 0.002 ms: json2 = jObject;
• 0.06 ms: json2 = jObject; json2 += "a";
• 0.11 ms: json2 = jObject; json2 += "alphabet soup alphabet soup alphabet soup alphabet soup alphabet soup alphabet soup alphabet soup ";
• 0.06 ms: json2 = jObject; json2 = json2 + "a";
• 0.06 ms: json2 = jObject; json2 = "a" + json2 ;

### JSON Performance

#### Construct a JSON string

• 5.70 ms: jObject = llList2Json(JSON_OBJECT, ["alpha", "0", "beta", "1", "gamma", "2", "delta", "3", "epsilon", "4"]);
• 0.002 ms: jObject = "{\"alpha\":\"0\",\"beta\":\"1\",\"gamma\":\"2\", \"delta\":\"3\", \"epsilon\":\"4\"}";

#### Extract data from a JSON string

• 4.64 ms: ix = (integer) llJsonGetValue(jObject, [target]);
• 6.12 ms: list parsed = llJson2List(jObject); ix = (integer) findValue(parsed, target);
• 5.74 ms: list parsed = llJson2List(jObject);
• 10.16 ms: list parsed = llJson2List(jArray); // 25-element array

#### Extract multiple values from a JSON string

(memory values calculated by storing llGetUsedMemory() before the loop, and subtracting that from llGetUsedMemory() after the loop.)

• 20.08 ms, -46 bytes(?!): a = llJsonGetValue(jObject, ["alpha"]); ... e = llJsonGetValue(jObject, ["epsilon"]);
• presumably a garbage collection happened in there
• 6.68 ms, 426 bytes: lList1 = llJson2List(jObject); a = findValue(lList1, "alpha"); ... e = findValue(lList1, "epsilon");
• 6.50 ms, 442 bytes: lList1 = llJson2List(jObject); a = llList2String(llListFindList(lList1, ["alpha"]) + 1); ... e = llList2String(llListFindList(lList1, ["epsilon"]) + 1);

#### Modify/add to a JSON string

• 6.69 ms: json2 = llJsonSetValue(jObject, ["alpha"], "5");
• 6.93 ms: json2 = llJsonSetValue(jObject, ["epsilon"], "5");
• 7.31 ms: json2 = llJsonSetValue(jObject, ["zeta"], "5");
• 0.062 ms: json2 = jObject + "{\"not really\":\"part of the object\"}";

### Conclusions

• List searching and extraction is MUCH faster than llJsonGetValue (well over an order of magnitude)
• Creating JSON strings by hand or through string concatenation is FAR more efficient than using llList2Json.
• For extracting multiple values from a JSON object, it's substantially faster (but probably not an order of magnitude faster) to use llJson2List once, then extract data from the list.
• The LSL string manipulation functions (llSubStringIndex, llGetSubString, llDeleteSubString, llInsertString) are individually slower than JSON functions, but for performing any full operation on a JSON string (i.e. search for an old value, replace it with a new one), the JSON functions almost certainly are more efficient.
• Compared with using lists, using JSON strings is a lot slower. However, it may be more efficient in memory usage, and certainly can make for much more readable code and data, and this may be sufficient to offset the performance penalty.
• When using list functions, let LSL convert a string to a one-element list automatically
• llList2Integer(...) is faster than (integer)llList2String(...)