Jump to content

Parsing each character of a string to a list


Guest
 Share

You are about to reply to a thread that has been inactive for 2913 days.

Please take a moment to consider if this thread is worth bumping.

Recommended Posts

I am a bit tired today and might be missing something obvious. I couldn't find any easy way to parse each single character of a string as an item of a list. The string is made up of 201 characters.

I have written a small script that does it, but it seems to take +/- 0.8 seconds which is quite long. My script will have to call that function quite often and there might be several people on the sim, using the HUD simultaniously. Does anyone have an idea how to do this with less resources? Maybe there is a way to apply llParseString2List that I have overlooked?

default
{
    state_entry()
    {
        llOwnerSay(llGetTimestamp());
        string my_string = "100000000000000000000000000000000000000090000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009";        
        integer length = llStringLength(my_string);
        integer w; 
        list newList;
        for(w = 0; w < length; w++)
            {
            newList += [llGetSubString(my_string, w, w)];
            }
        llOwnerSay(llGetTimestamp());
llOwnersay(llCSV2List(newList); } }
Link to comment
Share on other sites

I can't think of an easy, quick solution off the top of my head.  If you are hoping to test whether any of those digits have changed from one snapshot to the next, though, you could break the string up into smaller chunks and test them.  Start with a dummy global list, glOldValues, that looks like

glOldValues = [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1];

and then test each time with something like

integer i;while (i < 20){    integer new_value = (integer)llGetSubString(my_string,i*10,(i*10)+9);    if ( new_value != llList2Integer(glOld_values,i) )    {        glOld_Values = llListReplaceList(glOldValues,[new_value],i,i);        // Now use your algorithm to look only at the digits in this shorter chunk of my_string        OneCharacterAtATime(new_value);  // This is your current algorithm    }    ++i;}

With any luck, you won't have changes in each of the 20 substrings of my_string each time you test, so you'll only need to use your one-digit-at-a-time algorithm on one or two of the substrings instead of the whole bloody mess.

 

Link to comment
Share on other sites

This seems to take between about 0.55 and 0.69 seconds, so it does appear to be rather faster than a for(  ) loop.

default{    state_entry()    {                string my_string = "100000000000000000000000000000000000000090000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009";                integer counter = -llStringLength(my_string);        integer w;         list newList;        do{          newList+=[llGetSubString(my_string, counter,counter)];        }        while(++counter);        llOwnerSay((string)llGetTime());        llOwnerSay(llList2CSV(newList));    }}
Link to comment
Share on other sites


steph Arnott wrote:

Can not get my head around the reason for that, but as an winner for creating the most lag inducing script that idea must be in the top ten.

Why don't you like it, steph?   All it does is perform 201 operations as fast as it can, and then stops.   I'd have thought repetitive things like a fast llSensorRepeat, or an open listener on 0 on a busy region, or a fast temp rezzer whole degrees of magnitude worse than this.

I know you said a top 10, but if this is at the bottom end of the top 10 then I think the first three or four examples, at least, will be in a completely different league.

Link to comment
Share on other sites

It will all be good. I realized that the HUD only needs to perform the operation once, when it is attached.So it will be no lag disaster...    ;-)

About the logic and because I made you wondering: The script does download the game progress from the server when the HUD is attachedd. There are 200 non-linear game events that can be non-completed (=0) or not completed (=1). Yesterday I realised that the URL lenght for LSL-PHP-SQL communication is restricted. I is not long enough to communicate the player key and 400 characters of list content +commas.

So for transmitting it to the server, I convert the list into a string without commas which is easy and fast in LSL. When receiving info from the server, it needs to be converted back into the list which is obviously more complicated.

Last but not least you might say: "Wait there is not only 0 and 1, but also a 9 in your string." These numbers are leftovers from my tests with PHP where it would cut the string. It's easier to spot than counting all the zeros.

 

Link to comment
Share on other sites


Estelle Pienaar wrote:

It will all be good. I realized that the HUD only needs to perform the operation once, when it is attached.So it will be no lag disaster...    ;-)

About the logic and because I made you wondering: The script does download the game progress from the server when the HUD is attachedd. There are 200
non-linear
game events that can be non-completed (=0) or not completed (=1). Yesterday I realised that the URL lenght for LSL-PHP-SQL communication is restricted. I is not long enough to communicate the player key and 400 characters of list content +commas.

So for transmitting it to the server, I convert the list into a string without commas which is easy and fast in LSL. When receiving info from the server, it needs to be converted back into the list which is obviously more complicated.

Last but not least you might say: "Wait there is not only 0 and 1, but also a 9 in your string." These numbers are leftovers from my tests with PHP where it would cut the string. It's easier to spot than counting all the zeros.

 

Hmmm.... if it's all 1 or 0 then the 200 values could be mapped over a handful of integers.   Although setting and testing bits isn't trendy or anything.

Link to comment
Share on other sites

Yes I could do that. Yes I should do that. Thanks for pointing me to the obvious solution. Or to say it with Homer Simpson:    :matte-motes-oh-rly:

 



 

EDIT: Or let's say I will look into it when I have time. After all, the loop-parsing from string to a list only takes place once when the HUD is attached and is therefore not as resource demanding (as I originally feared). Changing the calculation process from list-based to string-based means rewriting the core game engine from scratch and I got other things on my plate right now...

 

EDIT 2: It is possible that having to operate with substrings every time that an event happens is more resource demanding than parsing a list once and then always checking the list. I would need to test that too. Anyway, thank you very much for all your feedback and ideas. It's much appreciated.

Link to comment
Share on other sites


Estelle Pienaar wrote:

About the logic and because I made you wondering: The script does download the game progress from the server when the HUD is attachedd. There are 200
non-linear
game events that can be non-completed (=0) or not completed (=1). Yesterday I realised that the URL lenght for LSL-PHP-SQL communication is restricted. I is not long enough to communicate the player key and 400 characters of list content +commas.

 

Have you considered using Experience Tools and storing the game progress as a KVP value?   The maximum size of a value is 4095 characters, apparently, so plenty large enough for your purposes,and then the only conversion you would need to do when you read the value would be llCSV2List.

It would have the added advantage that you are storing your data on LL's servers, and not having to rely on a third-party server (or pay to have it hosted).

Link to comment
Share on other sites

There could be a relatively big different in resource use. The whole loop itself is an "extra" step so that adds quiet a bit of resource use compared to a single llGetSubString(). Even to check the list you'd still need to use an llList2... which is probably already equivelant to the llGetSubString(), but some can correct me if I am wrong.

Link to comment
Share on other sites

Like I said in my last post: The loop in order to change from string to list has to be done only once. Afterwards, in the game itself, the engine is (right now) based on lists. And there are triggers for events all the time, and these events should be efficiently scripted, right?

The string/list does not only contain the events, but also conditions. A trigger can result in several game events that might already have been played etc. and everything needs to be looked up in the string/list and it needs to be modified. There are many functions going on based on the list all the time.

So it is not one single llGetSubString() vs. one single list operation. It means changing the list/string itself all the time. You would e.g. need to break up and merge the string with a new value at different positions all the time. It can probably be done more efficient with llListFindList and llListReplaceList.

Maybe there is no difference in efficiciency but I think there is.

Link to comment
Share on other sites

You are welcome.

Key value pairs are not without their limitations, of course.   All you can do with them is store, retrieve, update and delete data.   You can't run queries or anything like that.

However, we've been asking LL for persistent storage for ages and they do make a big difference.   I use them a lot.

To my mind, properly used they have the potential to revolutionise games (and particularly combat games) in SL.  

Link to comment
Share on other sites

The 4095 character limit in a KVP string can be annoying at times, but your string in this case is well within that limit.  If you ever have strings that are longer, you can always just chop them into pieces and save them as separate KVP to be stitched back together when you read them later.

Link to comment
Share on other sites


Qwalyphi Korpov wrote:

Hmmm.... if it's all 1 or 0 then the 200 values could be mapped over a handful of integers.   Although setting and testing bits isn't trendy or anything.

Yeah, this is the "correct" answer, I think. It's not a heck of a lot of logic to map the full range of binary choices into an index on a list of integers and a bit in that integer, instead of an index into a long list of strings, or a character position in a long string. I mean, if I were going to adopt a new representation, I think this would be the target, regardless of whether I used Experience KVP or an external database to persist the values.

Link to comment
Share on other sites

You are about to reply to a thread that has been inactive for 2913 days.

Please take a moment to consider if this thread is worth bumping.

Please sign in to comment

You will be able to leave a comment after signing in



Sign In Now
 Share

×
×
  • Create New...