• Listen to a special audio message from Bill Roper to the Hive Workshop community (Bill is a former Vice President of Blizzard Entertainment, Producer, Designer, Musician, Voice Actor) 🔗Click here to hear his message!
  • Read Evilhog's interview with Gregory Alper, the original composer of the music for WarCraft: Orcs & Humans 🔗Click here to read the full interview.

Arrays and hashtables

Status
Not open for further replies.
Level 7
Joined
Apr 5, 2011
Messages
245
I am noob and I want to know how big is difference between using arrays with unit indexing and hashtables.

For example, I want each unit having stamina. So, I can use array stamina[] or hashtable.

?
 
Level 9
Joined
Jul 10, 2011
Messages
562
for your example id recommend hashs because that way your able to easily connect the stamina value to each unit....would recommend 2 arrays otherwise.

for the difference and all informations read this
 
Level 7
Joined
Apr 5, 2011
Messages
245
There is almost nothing about difference as I see. "Hashtables are slower than arrays" - and that's all. But what is really wondering me, it's JASSers use them both often.

So, my idea is to take PUI and make a lot of arrays (because stamina was just an example). Am I right? And am I right if the most of properties are very special, only for 1% of units? Should I make separated indexing for them? Or should I use hashtable? ...
 
Level 9
Joined
Jul 10, 2011
Messages
562
1. i dont know PUI....just know that its an unit indexing.

2. why making masses of arrays instead of 1 hash?

3. tell me what you wanna do exactly and ill tell you the (at least in my opinion) best way to do it ^^
 
Level 16
Joined
Oct 12, 2008
Messages
1,570
The first big difference is that arrays can only hold indices from 0 to 8191, while hashtables can hold any value that fits in a 32-bit integer..

Then there is the way of handling it. Though, if you would use a hashtable, I would strongly suggest to use Table by Bribe, since it makes you not use one hashtable per system/resource, but rather one hashtables for everything you need..
 
Level 33
Joined
Mar 27, 2008
Messages
8,035
There is almost nothing about difference as I see. "Hashtables are slower than arrays" - and that's all. But what is really wondering me, it's JASSers use them both often.
Let me give you a morning lecture about the difference between Indexing and Hashtable (well, it's morning at my time).

INTRODUCTIONS
Both method (Indexing and Hashtable) uses arrays in the process. Indexing is a 1D array (Unit[0]) while Hashtable is a 2D arrays (Unit[0][0]) which uses child key and parent key to determine which unit is which while Indexing uses only 1 key (Integer) to assign a value (Index) to a unit.
HASHTABLE
By using this method, it allows you to overwrite a data to a certain unit, it is useful enough if you're making a trigger that needs to be overwritten, for example, a buff trigger. Well, you know that buffs are reset each time you are affected to it while it's still on that unit, right ? For instance, you have Roar buff that lasts for 10 seconds. At the last remaining 3 seconds, you would cast Roar again, what would happen ? Ah yes, the buff is reset to 10 seconds, right ? This is where Hashtable comes in handy.

It also allows you to use a Direct Search Algorithm which would speed up the performance compared to Indexing which uses Binary Search Algorithm - the larger the index , the heavier the process (it depends on the object's index value too).

Hashtable can save values (Integer, Real, Boolean, etc) to an object that does not even exist in the map. Let's say you want to save a value of '200' to Item A, so when you pick up Item A (not initially on the map), and once you load to the correct path, you will get the 200 value from that Item. Basically, hashtable saves value to that Item Type, which will affect the Item associated with it.

INDEXING
The main difference between Indexing and Hashtable, is that Indexing allows you to stack a data to a single object while Hashtable overwrites it. Imagine you have a spell that deals 50 damage per second when applied to a target unit and lasts for 10 seconds. Let's say you have 3 units having this ability and all of them cast at separately at interval of 1 second each. The damage dealt to that unit per second would (50 + 50 + 50) 150 damage per second, and each of the duration has its own timer. Like for the first cast, it would lasts 10 seconds, while the second cast would end 9 seconds after first cast, while the third cast would end 8 seconds after first cast.

Indexing as I said, uses a Binary Search Algorithm, it will loop until you hit the correct index value. Imagine your object has index value of 30, meaning that it will loop 30 times before it finds the index value for it, you can terminate the loop by setting the current looping integer to maxIndex.

It is faster than Hashtable because the fact it is only 1D array compared to 2D array (Hashtable). The Binary Search Algorithm can be ignored if compared to arrays that has different dimensions.
The way I see it, the main difference you should know is that Indexing offers data stacking while Hashtable offers data overwriting, that's it. Don't compare speeds, just focus on the goal you want to achieve (either Stacking or Overwriting).

Well, that is my point of view, I did not say that every statement I made there is correct, but that is from my experience dealing with Hashtable and Indexing.
If there are mistakes, kindly point it to me and explain the real definitions based from my statements, thank you :)
 
Level 33
Joined
Mar 27, 2008
Messages
8,035
Many people often confused Indexing and Unit Indexer.
Let me give you an equation for you to understand this a bit.

Indexing IS NOT Unit Indexer
Indexing IS NOT HASHTABLE

BUT

Hashtable IS Unit Indexer

Now you must be confused, how can Hashtable = Unit Indexer (it has the word "Index" in it).

Basically, Unit Indexer is a Hashtable which uses Custom Value to replace parent key which will make it to become a 1D array instead of 2D.

Basically, the application is the same method as Hashtable (Unit Indexer overwrites data) but it is said to be more faster than Hashtable.

So, what is the use of Hashtable if we already have Unit Indexer ?
This is where Hashtable beats Indexing.

Like I said at my previous post, Hashtable allows you to save values to an object that does not even exist in the map yet, right ?

However, Unit Indexer can't do that, it can't save values to an object that does not exist in the map yet because it assigns value when unit enters the map or initially in the map, but not from the map's Object Editor.

Hashtable allows you to save '200' to a unit named Paladin so when Paladin is summoned in the map, you can load the value from the UNIT TYPE of that UNIT to get the value 200.
 
actually you can save things for non-existent things into arrays too [using normal indexing, not UNIT indexing because unit indexing is obviously for units existent on the map already]... but of course hashes do it directly so it is better to use hashes for that...

but assuming he's using vJASS, then Bribe's Table will be a better way of doing that... shorter to write too because you use it like an array...

afaik, unit indexer systems just sets the unit's custom value to it's "map index" value (most probably based on the order that it appeared on the map for unit's dynamically added) which is why its faster (uses CV directly, no arrays or hashes needed)... that is before index recycling...

example: if there is no unit preplaced on the map, then the first unit to be created will be given a custom value of 1, the next one will have a cv of 2 and so on...
 
Level 33
Joined
Mar 27, 2008
Messages
8,035
Lol no idea he was a vJASSer ;p

Well, if my point of view (GUI Side), I would base this system from a Hashtable because it allows a data overwriting, instead of data stacking (why would you want to stack stamina lol).

And by means of Hashtable, you can use Unit Indexer in it, because the "stamina" is assigned to units when they enter the map and initially on the map, right ?
 
yes, though using hashes for just one purpose is not really good... but if he's gonna use it for multiple things then hashes will be better...

but why won't you be able to overwrite data in an array and why won't hashes be able to stack data??? just curious...

or do you actually mean stacking in a sense that you can have multiple instances of the thing (like stamina) on a single unit?

but anyway, you can overwrite data in an array and "stack" data in a hash...
 
Level 33
Joined
Mar 27, 2008
Messages
8,035
The only way I see to stack data in Hashtable is by spawning dummy for each instance (tested before and it works like Indexing).

Problem is, it requires unit to hold that the data, while Indexing requires none of it at all and serves the same purpose, that's why Indexing is favored for data stacking.
 
Technically, hashtables are also considered as arrays but can hold huge millions of instances using an ID of a handle (unit, timers, locations, destructables etc...)...

The problem of HT is the 'recalling' or loading of the saved data, since there are only a few functions that can recall data of that handle (e.g. unit==PIck Every UNit, timer==getexpiredtimer)...HT is best suitable on systems, not spells...

vJass on the other hand uses structs which is indexing itself, thus combining Table (multi-hashtable) makes it suitable to anything with unlimited instances...
 
Level 7
Joined
Apr 5, 2011
Messages
245
Thank you, guys! I have understood almost everything I wanted.
And the last question: is it stupid to make separated unit indexing for special units having such parameters that nobody else have and no having some of other have? What's more significant, lesser array and its full use or bigger array and faster unit indexing, how do you think?
 
Level 40
Joined
Dec 14, 2005
Messages
10,532
Looping through all indices on a timer is a fine thing, but when it comes to search which object is which, indexing is bad.
You know what I mean, right ?

Yeah well, both has pros and cons, truly depends on the situation.
Of course, hence why I said it depends on the situation. That said, I rarely want to do that with anything other than timers, in which case I just attach a struct to the timer with TimerUtils since it's easier.

Thank you, guys! I have understood almost everything I wanted.
And the last question: is it stupid to make separated unit indexing for special units having such parameters that nobody else have and no having some of other have? What's more significant, lesser array and its full use or bigger array and faster unit indexing, how do you think?
I would either just have the extra fields even when I wasn't using them, or (in vJass) have a place to attach a struct with additional data.
 
Level 23
Joined
Apr 16, 2012
Messages
4,041
its really just an opinion war here, one says oh hash shit!, baassee only abuses struct indexing :D(correct me if Im wrong) and other uses arrays. It doesnt matter how you do it as long as it works, really even you were talking about performence difference, all I can say is wtf? one eye blink takes so long I could add values to thousands of childkeys in same parent key in one hashtable and difference between calling SaveWhatEver and set whatever[index] is like what, 0.0001 second? lol

Also I suggest using hashtables over arrays as arrays eat space(yes this is another what, its only some bytes but when you have hundreds of array variables its getting some size) because you can add multiple parameters to the same unit using some indexing system and just inserting index of given unit to parent key and changing(overwriting as Defskull calls it and its more right in terms of what happens) the values to whatever you want.
For example: if I wanted to have stamina and spirt(yea wow but w/e nothing comes to my mind right now its quite late here as well) I would have to use 2 array variables and if I wanted to rewrite them it may be O(n) but using hashtable, we need only 1 parent key of hashtable, hashtable gives us oppoturninty to use O(1) if used correctly(array can be as well O(1) if used correctly) and also I need only one hashtable for all map not like we are using 255(256) hashtables, one for each spell or so(getting little off topic here). I would rather just call 2 times SaveInteger or SaveReal then using 2 fat ass arrays.
Also hashtable can have 5 different things saved in one field at the same time(integer, real, boolean, string and any handle at the same parentkey, childkey at the same time)
 
Level 22
Joined
Nov 14, 2008
Messages
3,256
Remind me again when all spells in GUI form uses only 1 hashtable for all of them instead of 1 hashtable/spell. And yes I do know that arrays takes shitload of space compared to a non-arrayed variable that's why I try to prevent it by saying that it's useless to store things like this:

Real[1] = X
Real[2] = XX
Real[3] = XXX

And waste 8187 indexes and instead set it Real[CurrentIndex] = lvl*x. However I find myself going rather off-topic at this very moment.
 
edo494 said:
Also I suggest using hashtables over arrays as arrays eat space(yes this is another what, its only some bytes but when you have hundreds of array variables its getting some size) because you can add multiple parameters to the same unit using some indexing system and just inserting index of given unit to parent key and changing(overwriting as Defskull calls it and its more right in terms of what happens) the values to whatever you want.

Hashtables eat space too. Every time something is stored, it uses memory to keep track of it. Just like an array. Hashtables are known as associative arrays.

Arrays are generally easier to work with (nicer interface and easy to declare). The limitation is that you can only use an index of 0-8191. That is usually the case where we switch to hashtables--when we want to use bigger numbers as keys and values. The other cases are usually for simplicity (so you don't have to use indexing or other data structures), data tables, or for an easy O(1) complexity.

Remind me again when all spells in GUI form uses only 1 hashtable for all of them instead of 1 hashtable/spell. And yes I do know that arrays takes shitload of space compared to a non-arrayed variable that's why I try to prevent it by saying that it's useless to store things like this:

Real[1] = X
Real[2] = XX
Real[3] = XXX

And waste 8187 indexes and instead set it Real[CurrentIndex] = lvl*x. However I find myself going rather off-topic at this very moment.

I'm not 100% positive about this next statement, but the way Warcraft 3 allocates memory in terms of arrays is not an instant 0-8191 allocation. Memory is allocated depending on the indices you use. War3 allocates it by powers of 2. For example, if your max index size is 3 then it will only allocate memory for indices 0-4 (0 to 2^2). If your max index size is 1000, then it will allocate memory for indices 0-1024 (0 to 2^10). Note that this does not take into account whether you have used a total of 1000 slots. You could literally just do:
JASS:
globals
    real array x
endglobals

function Test takes nothing returns nothing
    set x[1000] = 5
endfunction

And it will allocate memory for all those indicies 0-1024. I guess in that way, arrays might seem a bit unfavorable but it is pretty rare to use indexes greater than 100 unless you are indexing widgets or manually hashing a value down to the index range. (for example: GetHandleId(h) - 0x100000)
 
Level 22
Joined
Nov 14, 2008
Messages
3,256
I do wonder about this PAF 'cause then we can rather set the array size in the globals block as well, don't you agree?

Also I do remember Vexorian stating that one arrayed variable still takes more space than 3 non-arrayed variables (4 as well) thus creating 3 different variables (of course it's not userfriendly in any way). Thus I also wonder if your statement is true, because if you only use the first 0-1 indexes then how can the size of the variable still be greater if not memory wise? And of course having a spell with more than 4 levels is rather stupid by the player due to the fact that then you cannot convert the object into an slk-table thus the loading time will be increased by a greater amount.
 
Level 40
Joined
Dec 14, 2005
Messages
10,532
I do wonder about this PAF 'cause then we can rather set the array size in the globals block as well, don't you agree?
That's how many elements it initializes (since GUI tries to avoid forcing the user to create most objects explicitly). The array max size is 8192. That said, warcraft 3 doesn't allocate all the memory for the array at once; it increases its size as needed (by powers of 2, if I recall correctly).
 
Level 22
Joined
Nov 14, 2008
Messages
3,256
That's how many elements it initializes (since GUI tries to avoid forcing the user to create most objects explicitly). The array max size is 8192. That said, warcraft 3 doesn't allocate all the memory for the array at once; it increases its size as needed (by powers of 2, if I recall correctly).

Blah I guess I screwed up what I was talking about. Never mind.
 
Status
Not open for further replies.
Top