Roku Developer Program

Join our online forum to talk to Roku developers and fellow channel creators. Ask questions, share tips with the community, and find helpful resources.
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
Rek
Visitor

Re: Associative Array Errors - n00b

Explicit types are good... I'd recommend something like this:


function pointCreate(x as Integer, y as Integer) as Object
return {
x: x,
y: y,

toStr: function() as String
return "point("+str(m.x)+", "+str(m.y)+")"
end function
}
end function

function main() as Void
points = [] ' Create a new array

' Create points, and add them to list
for x = 0 to 9
point = pointCreate(x, 10) ' All points have y-coordinate of 10
points.push(point)
end for

' Output points
print "The Points are: "
for each point in points
print point.toStr()
end for

' Example accessing single x, y
point = points[0] ' Get first Point
print "First Point's X: ";point.x
end function
0 Kudos
RokuJoel
Binge Watcher

Re: Associative Array Errors - n00b

@theEndless, I would just note that if you are trying to squeeze the maximum performance from your code, for example in a game, it is best to avoid using Associative Arrays if possible - array access for Associative Arrays is still significantly slower than accessing a linear array, even though we've did some of work to significantly improve AA performance.

- Joel
0 Kudos
TheEndless
Channel Surfer

Re: Associative Array Errors - n00b

"RokuJoel" wrote:
@theEndless, I would just note that if you are trying to squeeze the maximum performance from your code, for example in a game, it is best to avoid using Associative Arrays if possible - array access for Associative Arrays is still significantly slower than accessing a linear array, even though we've did some of work to significantly improve AA performance.

- Joel

Thanks for the note, but if accessing an AA is slow enough to make an appreciable difference in framerate, then there are some serious issues there...

Just to be sure, I just did the following test, which gave me the exact opposite results of what you are suggesting:
    a = [0, 0]
aa = { x: 0, y: 0 }
timer = CreateObject("roTimespan")

for loop = 1 To 10
timer.Mark()
for i = 1 to 100000
test = a[0]
next
?"A Loop:";timer.TotalMilliseconds()
timer.Mark()
for i = 1 to 100000
test = aa.x
next
?"AA Loop:";timer.TotalMilliseconds()
next


Output:
------ Running ------
A Loop: 179
AA Loop: 75
A Loop: 145
AA Loop: 70
A Loop: 77
AA Loop: 68
A Loop: 78
AA Loop: 73
A Loop: 78
AA Loop: 67
A Loop: 78
AA Loop: 69
A Loop: 78
AA Loop: 67
A Loop: 78
AA Loop: 69
A Loop: 76
AA Loop: 69
A Loop: 77
AA Loop: 70

In every loop, accessing the AA was ~10% faster.

That aside, note also that that's looping over the AA 100,000 times, which is nowhere near what you'd realistically need to do in a single frame of animation. Reduce that to 1000 loops, and the processing time is almost immeasurable.

EDIT: I just ran the same test on the Roku 2 and got slightly different results, but still nothing significant enough to be concerned about it affecting framerate, IMO.
------ Running ------
A Loop: 211
AA Loop: 149
A Loop: 140
AA Loop: 148
A Loop: 150
AA Loop: 149
A Loop: 135
AA Loop: 154
A Loop: 138
AA Loop: 154
A Loop: 138
AA Loop: 151
A Loop: 136
AA Loop: 147
A Loop: 135
AA Loop: 151
A Loop: 139
AA Loop: 147
A Loop: 137
AA Loop: 148
My Channels: http://roku.permanence.com - Twitter: @TheEndlessDev
Instant Watch Browser (NetflixIWB), Aquarium Screensaver (AQUARIUM), Clever Clocks Screensaver (CLEVERCLOCKS), iTunes Podcasts (ITPC), My Channels (MYCHANNELS)
0 Kudos
Rek
Visitor

Re: Associative Array Errors - n00b

"TheEndless" wrote:
"RokuJoel" wrote:
@theEndless, I would just note that if you are trying to squeeze the maximum performance from your code, for example in a game, it is best to avoid using Associative Arrays if possible - array access for Associative Arrays is still significantly slower than accessing a linear array, even though we've did some of work to significantly improve AA performance.

- Joel

Thanks for the note, but if accessing an AA is slow enough to make an appreciable difference in framerate, then there are some serious issues there...

Just to be sure, I just did the following test, which gave me the exact opposite results of what you are suggesting:


Great minds think alike. I just finished doing the same thing with similar results:


function main() as Void
timer = createObject("roTimespan")
accessCount = 0

' Setup map containing alphabet
map = {}
for i = asc("a") to asc("z") - 1
map[chr(i)] = i
end for

' Create array containing only keys to the map.
keys = []
for each key in map
keys.push(key)
end for

' Time the whole loop without the AA lookups. This will be used as the
' 'maintenanceTime' (i.e. time to perform loop iterations and increment
' counter)
timer.mark()
for i = 0 to 999999
for each key in keys
accessCount = accessCount + 1
end for
end for
maintenanceTime = timer.totalMilliseconds()

' Perform 1 million lookups on each element in AA.
accessCount = 0
timer.mark()
for i = 0 to 999999
for each key in keys
elem = map[key]
accessCount = accessCount + 1
end for
end for

' Calculate total elapsed time.
elapsed = timer.totalMilliseconds() - maintenanceTime

' Results
?"Iterations : ";accessCount
?"Total Ellapsed: ";elapsed;" ms"
?"Average Time : ";(elapsed / accessCount)
end function


And here are my results on Roku 3:

Iterations : 25000000
Total Ellapsed: 19830 ms
Average Time : 0.0007932


It looks like it takes ~0.0008 ms to perform AA lookup.
0 Kudos
Komag
Roku Guru

Re: Associative Array Errors - n00b

Maybe very short keys help it be faster? Same results with keys that are many character's long?
0 Kudos
TheEndless
Channel Surfer

Re: Associative Array Errors - n00b

"Komag" wrote:
Maybe very short keys help it be faster? Same results with keys that are many character's long?

Increasing the length of the key does seem make a difference, but still not significant enough, in my opinion, to warrant abandoning the use of AAs when working with the 2D API.

Now, changing from the shorthand dot notation to brackets makes a huge difference (e.g., aa.key vs aa["key"]), nearly doubling the processing time, so I'd avoid using key names that require brackets whenever possible.
My Channels: http://roku.permanence.com - Twitter: @TheEndlessDev
Instant Watch Browser (NetflixIWB), Aquarium Screensaver (AQUARIUM), Clever Clocks Screensaver (CLEVERCLOCKS), iTunes Podcasts (ITPC), My Channels (MYCHANNELS)
0 Kudos
RokuJoel
Binge Watcher

Re: Associative Array Errors - n00b

sometimes, it is really great to be wrong. Thanks for the benchmarks!

- Joel
0 Kudos
TheEndless
Channel Surfer

Re: Associative Array Errors - n00b

"RokuJoel" wrote:
sometimes, it is really great to be wrong. Thanks for the benchmarks!

- Joel

Hey Joel, any idea why aa["key"] is so much slower than aa.key? I'd have expected the opposite to be true.
My Channels: http://roku.permanence.com - Twitter: @TheEndlessDev
Instant Watch Browser (NetflixIWB), Aquarium Screensaver (AQUARIUM), Clever Clocks Screensaver (CLEVERCLOCKS), iTunes Podcasts (ITPC), My Channels (MYCHANNELS)
0 Kudos
RokuMarkn
Visitor

Re: Associative Array Errors - n00b

With aa.key the hash of the key name can be computed at compile time. With aa[var], it needs to be done at runtime. When var is a literal string it's possible it could also be done at compile time but I think the compiler treats a string as a var in this case and defers it to runtime.

--Mark
0 Kudos
NewManLiving
Visitor

Re: Associative Array Errors - n00b

Associative Arrays also offer a limited type of object containment which is a natural fit for BS, ( consider GetGlobalAA ). They provide a means to contain data and methods which act upon that data using the m pointer. For code intensive applications such as the 2D API, Associative Arrays are a very efficient way to build complex frameworks. While there is no Base Class inheritance per-say, Function pointers can be overridden to act upon the base data in extended classes. The extended class would create an instance of the base class and provide another method for the base function pointers. These overrides should be assigned in the new objects initialization function and not in the new objects declaration. This also makes it easy to adapt to different ROKU environments as dictated by device objects. Serious programmers would do well to learn how to use them beyond a "dictionary". While the m pointer is limited to the contents of the AA, member references of the new AA can be set to global Objects during declaration and then used naturally.
My Channels: 2D API Framework Presentation: https://owner.roku.com/add/2M9LCVC
Updated: 11-11-2015 - Completed Keyboard interface
The Joel Channel ( Final Beta )
0 Kudos