Author Topic: Technical Question - GetObjectByTag or...  (Read 2200 times)

Legacy_FunkySwerve

  • Hero Member
  • *****
  • Posts: 2325
  • Karma: +0/-0
Technical Question - GetObjectByTag or...
« Reply #15 on: August 21, 2011, 03:04:40 am »


               

henesua wrote...

That said... I certainly wasn't doubting you and pressing for your data. I just wanted to know what you thought on the matter.

Lol, I didn't think you were - I just like to put all the data I have on a topic out there. Knowing how many places are in your mod, or the average per area, or per tile, can come in handy. '<img'>

One reason that I'm highly skeptical of the 1k placeable per area claim is that even a couple hundred places in a small enough space can cause huge amounts of lag, as the server updates the description for the client every time they come into visual range. We actually had to move our Pillar of Skulls in Avernus for this reason - it's original position was too close to the Tiamat fight in the area, and players moving in and out of sight of it was generating immense amounts of lag.

Anyway, what he's saying runs counter to all my experience, but who knows, maybe they optimized GObT in one of the later updates. If he's not going to show any profiling, though, I have no reason to suspect that that's the case. As you say..show it or it didn't happen. '<img'>

Funky
               
               

               
            

Legacy_FunkySwerve

  • Hero Member
  • *****
  • Posts: 2325
  • Karma: +0/-0
Technical Question - GetObjectByTag or...
« Reply #16 on: August 21, 2011, 03:10:06 am »


               

Mavrixio wrote...
I dont have the formula on the top of my  head, but the time that it takes to access an element in a sorted array can be considered as constant... so no matter the size of your module, GetObjectByTag will be relatively fast, it can easely be faster than GetLocalObject if you have many variables on the source.

Faster than GetLocalObject? That's even harder to believe. By the way, someone did some profiling a while back that shows that variable read times don't noticeably increase until you hit around 5k variables on an object, so the claim that this is only the case 'if you have many variables on the source' smells a bit too - I've yet to see an application outside the PRC Character Creator that slammed even close to that many vars on an object - even counting things like dynamic convo pseudoarrays, which only hit a couple hundred vars.

Do you have ANY profiling on GObT? You're making me very curious, if nothing else... '<img'>

Funky
               
               

               
            

Legacy_Mavrixio

  • Full Member
  • ***
  • Posts: 142
  • Karma: +0/-0
Technical Question - GetObjectByTag or...
« Reply #17 on: August 21, 2011, 04:28:20 am »


               Script:
void TestLocalVars(int nCount)
{
   object oTest = CreateObject(OBJECT_TYPE_WAYPOINT, "nw_waypoint001", GetStartingLocation());
   int i;
   for (i=0; i<nCount; i++) SetLocalObject(oTest, IntToString(i), oTest);
   StartTimer();
   for (i=0; i<10000; i++) GetLocalObject(oTest, "test");
   SendMessageToPC(OBJECT_SELF, IntToString(nCount)+"vars: " + IntToString(EndTimer())+"ms");
   DestroyObject(oTest);
}

   //test of GetLocalObject
   TestLocalVars(10);
   TestLocalVars(20);
   TestLocalVars(100);
   TestLocalVars(200);
   TestLocalVars(500);
   TestLocalVars(1000);
   TestLocalVars(2000);
   //test of GetObjectByTag
   StartTimer();
   for (i=0; i<10000; i++) GetObjectByTag("theres no objects with this tag");
   SendMessageToPC(oPC, "GetObjectByTag: " + IntToString(EndTimer())+"ms");
   //test of GetNearestObjectByTag
   StartTimer();
   for (i=0; i<10000; i++) GetNearestObjectByTag("theres no objects with this tag");
   SendMessageToPC(oPC, "GetNearestObjectByTag: " + IntToString(EndTimer())+"ms");  

Output:
[CHAT WINDOW TEXT] [Sat Aug 20 23:23:46] 10vars: 80ms
[CHAT WINDOW TEXT] [Sat Aug 20 23:23:46] 20vars: 80ms
[CHAT WINDOW TEXT] [Sat Aug 20 23:23:46] 100vars: 100ms
[CHAT WINDOW TEXT] [Sat Aug 20 23:23:46] 200vars: 120ms
[CHAT WINDOW TEXT] [Sat Aug 20 23:23:46] 500vars: 200ms
[CHAT WINDOW TEXT] [Sat Aug 20 23:23:46] 1000vars: 300ms
[CHAT WINDOW TEXT] [Sat Aug 20 23:23:46] 2000vars: 500ms
[CHAT WINDOW TEXT] [Sat Aug 20 23:23:46] GetObjectByTag: 30ms
[CHAT WINDOW TEXT] [Sat Aug 20 23:23:46] GetNearestObjectByTag: 590ms
[CHAT WINDOW TEXT] [Sat Aug 20 23:23:49] 10vars: 80ms
[CHAT WINDOW TEXT] [Sat Aug 20 23:23:49] 20vars: 80ms
[CHAT WINDOW TEXT] [Sat Aug 20 23:23:49] 100vars: 100ms
[CHAT WINDOW TEXT] [Sat Aug 20 23:23:49] 200vars: 110ms
[CHAT WINDOW TEXT] [Sat Aug 20 23:23:49] 500vars: 200ms
[CHAT WINDOW TEXT] [Sat Aug 20 23:23:49] 1000vars: 300ms
[CHAT WINDOW TEXT] [Sat Aug 20 23:23:49] 2000vars: 490ms
[CHAT WINDOW TEXT] [Sat Aug 20 23:23:49] GetObjectByTag: 30ms
[CHAT WINDOW TEXT] [Sat Aug 20 23:23:49] GetNearestObjectByTag: 580ms
[CHAT WINDOW TEXT] [Sat Aug 20 23:23:49] 10vars: 80ms
[CHAT WINDOW TEXT] [Sat Aug 20 23:23:49] 20vars: 80ms
[CHAT WINDOW TEXT] [Sat Aug 20 23:23:49] 100vars: 90ms
[CHAT WINDOW TEXT] [Sat Aug 20 23:23:49] 200vars: 120ms
[CHAT WINDOW TEXT] [Sat Aug 20 23:23:52] 500vars: 200ms
[CHAT WINDOW TEXT] [Sat Aug 20 23:23:52] 1000vars: 290ms
[CHAT WINDOW TEXT] [Sat Aug 20 23:23:52] 2000vars: 480ms
[CHAT WINDOW TEXT] [Sat Aug 20 23:23:52] GetObjectByTag: 30ms
[CHAT WINDOW TEXT] [Sat Aug 20 23:23:52] GetNearestObjectByTag: 640ms
[CHAT WINDOW TEXT] [Sat Aug 20 23:23:52] 10vars: 80ms
[CHAT WINDOW TEXT] [Sat Aug 20 23:23:52] 20vars: 80ms
[CHAT WINDOW TEXT] [Sat Aug 20 23:23:52] 100vars: 100ms
[CHAT WINDOW TEXT] [Sat Aug 20 23:23:52] 200vars: 120ms
[CHAT WINDOW TEXT] [Sat Aug 20 23:23:52] 500vars: 200ms
[CHAT WINDOW TEXT] [Sat Aug 20 23:23:52] 1000vars: 300ms
[CHAT WINDOW TEXT] [Sat Aug 20 23:23:52] 2000vars: 500ms
[CHAT WINDOW TEXT] [Sat Aug 20 23:23:52] GetObjectByTag: 30ms
[CHAT WINDOW TEXT] [Sat Aug 20 23:23:53] GetNearestObjectByTag: 690ms
               
               

               
            

Legacy_FunkySwerve

  • Hero Member
  • *****
  • Posts: 2325
  • Karma: +0/-0
Technical Question - GetObjectByTag or...
« Reply #18 on: August 21, 2011, 06:24:56 am »


               Interesting, but where are the Start and EndTimer functions? I've always used the NWNX profiler, which doesn't rely on in-script functions. And what size is the module? Object count? Objects in area? The amount of information you're leaving out isn't helping. Also, if you provide the full function and includes, I can run it on HG for comparison.

Funky
               
               

               


                     Modifié par FunkySwerve, 21 août 2011 - 05:26 .
                     
                  


            

Legacy_GhostOfGod

  • Hero Member
  • *****
  • Posts: 1490
  • Karma: +0/-0
Technical Question - GetObjectByTag or...
« Reply #19 on: August 21, 2011, 11:17:54 am »


               Curiouser and curiouser...
               
               

               


                     Modifié par GhostOfGod, 21 août 2011 - 10:18 .
                     
                  


            

Legacy_Mavrixio

  • Full Member
  • ***
  • Posts: 142
  • Karma: +0/-0
Technical Question - GetObjectByTag or...
« Reply #20 on: August 21, 2011, 11:37:34 am »


               StartTimer and EndTimer are custom nwnx functions like nwnx_timer on Windows.

The number of object in our module / the custom changes done to our nwserver, it wont reassure you '<img'>

What there's to know is that:
GetObjectByTag > GetLocalObject
GetNearestObjectByTag is not in the competition, you it only when you have no choice.
GetLocalObject get slightly slower with the number of variable on the object, but at a proportional speed... the performace of it could be calculated by (x + y * z) where x is the constant speed (slower that GetObjectByTag by itself, if you have a large module), y is the number of variables and z is performance decrease per variable (very small but after 300-500 variables you already doubled the default speed)
               
               

               


                     Modifié par Mavrixio, 21 août 2011 - 01:48 .
                     
                  


            

Legacy_Failed.Bard

  • Hero Member
  • *****
  • Posts: 1409
  • Karma: +0/-0
Technical Question - GetObjectByTag or...
« Reply #21 on: August 21, 2011, 12:50:08 pm »


                 I was curious about this myself, so I set up a test for it in my little mod using OnCick on placeables to trigger the scripts.  133 placeables in the area, exactly 100 barrell placeables placed between script trigger placeable and the placeable it was looking for, to simulate a somewhat crowded are.
  I'm not sure my complete mod placeable count, likely 1500-2000 though, since it's 50 areas.

 500 iterations of each search, in an attempt to get the run time high enough to compare.


  Script one, labeled unimaginatively "test_1"

 void main()
{
 object oTest;
 int i;
 for (i = 1; i <= 500; i ++)
    {
     oTest = GetObjectByTag ("TEST_FIND_ME");
    }
 SpeakString ("Done");
}


Script Two, "test_2"

void main()
{
 object oTest;
 int i;
 for (i = 1; i <= 500; i ++)
    {
     oTest = GetNearestObjectByTag ("TEST_FIND_ME");
    }
 SpeakString ("Done");
}


Run times:

test_1          0 msec        1 calls
test_2          38 msec      1 calls


I'll try it again with only 50 placeables between, to see how much of a speed difference it makes per placeable it has to check, but I expect it has to check every single placeable in the area, then compare tags and distances, so it'll still be substantially slower.


Edit:  50 between, 83 placeables total in area:

test_1           0 msec      1 calls
test_2          25 msec      1 calls

test_1          20 msec     10 calls
test_2         241 msec     10 calls
               
               

               


                     Modifié par Failed.Bard, 21 août 2011 - 12:01 .
                     
                  


            

Legacy_OldTimeRadio

  • Hero Member
  • *****
  • Posts: 2307
  • Karma: +0/-0
Technical Question - GetObjectByTag or...
« Reply #22 on: August 21, 2011, 02:32:32 pm »


               I have nothing to contribute to this discussion but I just wanted to cheer you folks on.  Knowing the more efficient of these methods, or which is more efficient in what situation, would be a huge help to me.  I'm not that great a sccripter to begin with so I need all the help I can get when it comes to efficiency of certain functions.
               
               

               
            

Legacy_FunkySwerve

  • Hero Member
  • *****
  • Posts: 2325
  • Karma: +0/-0
Technical Question - GetObjectByTag or...
« Reply #23 on: August 21, 2011, 03:36:12 pm »


               

Mavrixio wrote...

StartTimer and EndTimer are custom nwnx functions like nwnx_timer on Windows.

The number of object in our module / the custom changes done to our nwserver, it wont reassure you '<img'>

What there's to know is that:
GetObjectByTag > GetLocalObject
GetNearestObjectByTag is not in the competition, you it only when you have no choice.
GetLocalObject get slightly slower with the number of variable on the object, but at a proportional speed... the performace of it could be calculated by (x + y * z) where x is the constant speed (slower that GetObjectByTag by itself, if you have a large module), y is the number of variables and z is performance decrease per variable (very small but after 300-500 variables you already doubled the default speed)


I already know what you're claiming. I'm asking for data to help in verifying those claims. Again:

And what size is the module? Object count? Objects in area? The amount
of information you're leaving out isn't helping. Also, if you provide
the full function and includes, I can run it on HG for comparison.


Funky
               
               

               
            

Legacy_FunkySwerve

  • Hero Member
  • *****
  • Posts: 2325
  • Karma: +0/-0
Technical Question - GetObjectByTag or...
« Reply #24 on: August 21, 2011, 03:41:55 pm »


               

Failed.Bard wrote...

  I was curious about this myself, so I set up a test for it in my little mod using OnCick on placeables to trigger the scripts.  133 placeables in the area, exactly 100 barrell placeables placed between script trigger placeable and the placeable it was looking for, to simulate a somewhat crowded are.
  I'm not sure my complete mod placeable count, likely 1500-2000 though, since it's 50 areas.

It's not just placeables, remember, but all objects. Places are typically the most numerous types, but there's still other heavy hitters, like items, and triggers, along with creatures, doors, waypoints, etc.

Funky
               
               

               
            

Legacy_Failed.Bard

  • Hero Member
  • *****
  • Posts: 1409
  • Karma: +0/-0
Technical Question - GetObjectByTag or...
« Reply #25 on: August 21, 2011, 04:09:26 pm »


               

FunkySwerve wrote...

Failed.Bard wrote...

  I was curious about this myself, so I set up a test for it in my little mod using OnCick on placeables to trigger the scripts.  133 placeables in the area, exactly 100 barrell placeables placed between script trigger placeable and the placeable it was looking for, to simulate a somewhat crowded are.
  I'm not sure my complete mod placeable count, likely 1500-2000 though, since it's 50 areas.

It's not just placeables, remember, but all objects. Places are typically the most numerous types, but there's still other heavy hitters, like items, and triggers, along with creatures, doors, waypoints, etc.

Funky



  I used a test area to do it in.  With GetObjectByTag, the Lexicon says it checks through in this order:

OBJECT_TYPE_STORE (128)
OBJECT_TYPE_PLACEABLE (64)
OBJECT_TYPE_WAYPOINT (32)
OBJECT_TYPE_AREA_OF_EFFECT (16) (spell effects, like web)
OBJECT_TYPE_DOOR (8)
OBJECT_TYPE_TRIGGER (4)
OBJECT_TYPE_ITEM (2)
OBJECT_TYPE_CREATURE (1)

 

  I'm assuming GetNearestObjectByTag checks the same.  In that particular area, it was just placeables out of those, and my dm avatar triggering the switch, so there wouldn't have been any signifigant additional overhead that GetNearestObjectByTag needed to check through.
 
               
               

               
            

Legacy_FunkySwerve

  • Hero Member
  • *****
  • Posts: 2325
  • Karma: +0/-0
Technical Question - GetObjectByTag or...
« Reply #26 on: August 21, 2011, 08:19:46 pm »


               

Failed.Bard wrote...

  I used a test area to do it in.  With GetObjectByTag, the Lexicon says it checks through in this order:

OBJECT_TYPE_STORE (128)
OBJECT_TYPE_PLACEABLE (64)
OBJECT_TYPE_WAYPOINT (32)
OBJECT_TYPE_AREA_OF_EFFECT (16) (spell effects, like web)
OBJECT_TYPE_DOOR (8)
OBJECT_TYPE_TRIGGER (4)
OBJECT_TYPE_ITEM (2)
OBJECT_TYPE_CREATURE (1)

 

  I'm assuming GetNearestObjectByTag checks the same.  In that particular area, it was just placeables out of those, and my dm avatar triggering the switch, so there wouldn't have been any signifigant additional overhead that GetNearestObjectByTag needed to check through.
 


I was just pointing that out in case you'd misunderstood my focus on places in my earlier responses (the place count doc). If indeed GObT uses that ordering, that could well explain my experience - we have a fair amount of items in stores - enough that we had to put in separate shops for selling, to avoid massive lag spikes on close of the store. I may well wind up doing some profiling, if Mavrixio doesn't become a little more forthcoming with data.

Funky
               
               

               
            

Legacy_ffbj

  • Hero Member
  • *****
  • Posts: 1097
  • Karma: +0/-0
Technical Question - GetObjectByTag or...
« Reply #27 on: August 21, 2011, 08:49:00 pm »


               I remember this argument from the old boards, and as FS said theory and practice, well it was pretty much settled that gnobt was faster.  But what I am wondering is, just using basic logic, would not the time be dependent on the location of the object?  That is if you were standing right next to the object, assuming that it is checking from the focal point of the location where the function is called.  Of course I guess what is being said is that is not how the function works.  Also just pointing out the gnobt is very useful if you have multiples, more than one object with the same tag.  Of course that is probably why they have the function in the first place.Finally, maybe something useful, if speed was the paramount criterion would not something like using the object type be even faster?  As in object type placeable, store, etc... since you would cut out the needless search for objects that were not of that type? In other words a further refining of the search.
               
               

               


                     Modifié par ffbj, 21 août 2011 - 07:54 .
                     
                  


            

Legacy_Mavrixio

  • Full Member
  • ***
  • Posts: 142
  • Karma: +0/-0
Technical Question - GetObjectByTag or...
« Reply #28 on: August 21, 2011, 09:16:18 pm »


               The test was done in an area with 70 objects, The module has about 14k objects in its tag list.
               
               

               
            

Legacy_FunkySwerve

  • Hero Member
  • *****
  • Posts: 2325
  • Karma: +0/-0
Technical Question - GetObjectByTag or...
« Reply #29 on: August 21, 2011, 09:26:21 pm »


               There were also a ton of posts on the old board about speed of variable reads with X variables on them (also a long-settled dispute). Unfortunately finding them with the boards down is very difficult, and I didn't find the 5000-mark one I mentioned, but I did find a number of others, including remarks by Primogenitor (who studied it extensively when writing the PRC CCC) on 03/21/06 00:21:

The number of locals on the object being one though you have to get into thousands to make a difference. In 99% of cases, this will be the fastest method of reading or writing data. If you do have thousands of locals, its simple enough to split them over several objects with a couple of hundred on each.

.

Of course, were someone to present that to me, I would probably dismiss it as anecdotal, if I didn't know Primo or his work on the Conversation Character Creator, so meh. He also was NOT comparing GetLocalObject to other object-getting methods, but to other data-storage/retrieval methods - something I did a lot of comparison and profiling on myself.

As to placement of objects, I'll probably check that in my runs, if I wind up doing them. I'm also curious to know, as was speculated about on the last page, whether or not all objects in the area are looked at by GNObT, before the nearest of a tag is identified - I suspect they are. That would mean the placement of the reference object for the GN wouldn't matter, only the object count in the area.

As far as object types and speed, we use a combination of GetWaypointByTag and GetNearest to find objects quickly - GWbT is quite fast, in our experience, so there is some merit to limiting by object type. I'm unaware of any hash-like optimization there, either, however, so I would tend to be wary of adding too many waypoints to your mod (but then, I'm sure we have thousands total in HG).

I haven't done much profiling in the last couple of years, and it IS kind of fun... '<img'>

Funky