Jump to content

User Defined Function- IsInList()


Mitzpatrick Fitzsimmons
 Share

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

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

Recommended Posts

Well, in my opinion, yes my function is better because there is no need to define 2 seperate lists... using a list to hold a variable, say a string would require an additional function to retreieve that variable from the list (as in llList2String() ).

I do have a video tutorial that shows this (i think) in better detail.

 

http://www.youtube.com/watch?v=aua31oQJR4A&feature=player_embedded

Link to comment
Share on other sites

I agree.  ~llListFindList(data, [variable])  has the advantages of using a system function and operating without the inherent slowness of a for loop. Try this simple solution ....

 

list main_list = ["BOB", "JOE","SAM","JANE","SUE","PAM"];default{    state_entry()    {        llListen(-11223344,"","","");    }    touch_start(integer total_number)    {        llTextBox(llDetectedKey(0),"What are you looking for?",-11223344);    }    listen (integer channel, string name, key id, string msg)    {             if( ~channel = llListFindList(main_list,[msg]))            {                llSay(0, msg + " is in the main_list at position " + (string)channel);            }            else            {                llSay(0, msg + "is not in the main_list.");            }        }}

 

 

 

Link to comment
Share on other sites

I'm sorry, but I have to along with the majority here, too.  I don't see the advantage to running a loop as opposed to using ~llListFindList(list,[whatever i'm looking for]).   In fact, I remember getting told off (in the nicest possible way) by Jesse Barnett in the old, old forums for not doing precisely that.

Link to comment
Share on other sites

As comented by others above, there is no need of such user function because there is llListFindList() system call. There is however another problem with your code which I point out in here in hopes people would note and not repeat any longer.

You call a system method to determine the list length in each loop iteration:
   for(i=0; i < llGetListLength(data);i++) {... }
This wastes much resources. For instance if your list has 50 elements you are going to make 50 system calls. But only one is enough!
   integer n= llGetListLength(data);
   for(i=0; i < n;i++) {... }

Some compilers are smart enough to catch a thing like that and optimize but not the LSL compiler.

Link to comment
Share on other sites

Just another little efficiency thing for loops....

 

prefix notation is faster and uses less resources than postfix.  This is because the value doesn't have to be held for evaluation before operation.  So when using loops, especially, it's better to use ++i than to use i++ (or use --i rather than i-- if your loop is decrementing.)

 

Link to comment
Share on other sites

  • 2 months later...

In fact , the operator is not wrong  . And to use "== -1" or "~" is nearly the same .

 

But to use an user-defined function for one line is costly .

It seems , that randomly , the return of the user function is either in the same frame of the sim either the next frame of the sim .

So , the time spent is either  < 1 ms either 22 ms . Never between . 

 

This is a program to test it

integer IsInList(list data, string name){    if(llListFindList(data,[name]) != -1) return TRUE;    else return FALSE;}integer IsInList2(list data, string name){    if( ~llListFindList(data,[name])) return TRUE;    else return FALSE;}integer IsInList3(list data, string name){    return (llListFindList(data,[name]) != -1);}integer IsInList4(list data, string name){    return  ~llListFindList(data,[name]);}integer getTime(string stamp) // count milliseconds since the day began{    return (integer) llGetSubString(stamp, 11, 12) * 3600000 + // hh           (integer) llGetSubString(stamp, 14, 15) * 60000 +  // mm           llRound((float)llGetSubString(stamp, 17, -2) * 1000000.0)/1000; // ss.ff..f} default{    state_entry()    {    }     touch_start(integer total_number)    {        integer i = 1000000000;        integer j;        list l;        while ( i <= 1000000100 )        {            l += [ (string)i + "A" ];            i++;        }         integer NBITERS = 1000;        string t0 = llGetTimestamp();        for ( j = 1; j <= NBITERS; j++ )        IsInList(l,"1000000050A");        string t1 = llGetTimestamp();        for ( j = 1; j <= NBITERS; j++ )        IsInList2(l,"1000000050A");        string t2 = llGetTimestamp();        for ( j = 1; j <= NBITERS; j++ )        IsInList3(l,"1000000050A");        string t3 = llGetTimestamp();        for ( j = 1; j <= NBITERS; j++ )        IsInList4(l,"1000000050A");        string t4 = llGetTimestamp();        for ( j = 1; j <= NBITERS; j++ )         ~llListFindList(l,["1000000050A"]);        string t5 = llGetTimestamp();           for ( j = 1; j <= NBITERS; j++ )         llListFindList(l,["1000000050A"]) != -1;        string t6 = llGetTimestamp();                  llOwnerSay(llList2CSV([ getTime(t1)-getTime(t0),  getTime(t2)-getTime(t1), getTime(t3)-getTime(t2), getTime(t4)-getTime(t3), getTime(t5)-getTime(t4), getTime(t6)-getTime(t5)]));                       } }

 

The results give for instance


[01:16] Object: 12593, 12552, 12586, 12678, 8940, 8915
[01:18] Object: 12003, 12327, 12449, 12675, 8942, 8932
[01:19] Object: 13145, 13320, 13309, 13184, 8966, 8926

 

Inline versions are faster than user-functions . But "=-1" or "~" are equally fast .

With NBITERS = 1 it gives for instance

[01:27] Object: 1, 0, 21, 0, 23, 22
[01:27] Object: 0, 0, 0, 0, 0, 0
[01:27] Object: 0, 0, 0, 22, 0, 0
[01:27] Object: 0, 0, 0, 0, 0, 0
[01:27] Object: 0, 0, 0, 0, 0, 0
[01:27] Object: 0, 0, 0, 0, 0, 0
[01:27] Object: 22, 0, 0, 0, 0, 22
[01:28] Object: 0, 0, 0, 22, 22, 0
[01:28] Object: 0, 0, 0, 21, 0, 1
[01:28] Object: 1, 0, 0, 22, 0, 22
[01:28] Object: 0, 0, 0, 22, 0, 0
[01:28] Object: 0, 0, 0, 0, 22, 0
[01:28] Object: 0, 0, 22, 0, 23, 22
[01:28] Object: 0, 1, 0, 0, 0, 0

 

I don t know why people talk about loop . There are no loops.

Link to comment
Share on other sites

  • 7 months later...

The OP's Function has a couple of things that the replys have overlooked.

The first is that it returns a real Boolean result that equates to the TRUE and FALSE constants of LSL the ~ opperator does not.

This can be very important when you are manipulating several flags in a single integer or any other form of bitwise function.

It also has a serious failing in that it can only find a String in the Target List which limits its usability.

 The equivalent function that I have used for the past few years is:

integer inList(list data, list find){return !!~llListFindList(data, find);}

It still returns a real Boolean result and has the advantage that any data type can be found.

The disadvantage is that the "find" parameter must be cast to a list by using (list)find or [find] in the calling statement.

If you are using the preprocessor in the 3rd party Viewers (Only tested with Phoenix / Firestorm) then you can use:

#define inList(a,b) (!!~llListFindList(a, ))

It has the advantage of being able to find any data type in the list without having to cast find, it still returns a proper TRUE/FALSE (1/0) result, uses less memory, is faster and can be included in the code but will only be compiled if and when it is used.

Cheers

V

Link to comment
Share on other sites

llListFindList finds every data type - you just need to know the type. If you don't know it or have a mixup of string and numbers for example then llListFindList doesnt work. But in this case it's better you think about your code or have a very good reason for having and searching such a list.

Link to comment
Share on other sites

You are about to reply to a thread that has been inactive for 4215 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...