GMS 2 Which is faster?

M

Matthew Hoinville

Guest
I have a persistent invisible object called obj_game that controls most everything about my game:
Which button is pressed, whether or not we're in a cutscene, how far we've gone along in the story, and whether or not the game is paused.
[for example, if the variable global.paused = 1, the game is paused]

I have variables for all of this. Now, I'm trying to decide whether objects should call to these variables straight from the object or from a global variable. It doesn't affect my workflow in the slightest: it's simply a matter of choosing whether to write global.[variable] or obj_game.[variable]

What I want to know is: which one would run faster?
 
K

Kobold

Guest
I tend to use
Code:
object.variable
...much more than global.variable
but I don't really bother with putting a lot of thought into it... since it's 2018 and our hardware has become quite fast... so that you would have to reserve a lot of multi-dimensional arrays in order to bring things down to its knees.

I "think" that using a global is faster... since it doesn't need to check the container or class where it sits in... maybe?
 
I believe they will basically be the same. I seem to remember that Russell (or might have been Mike) at YYG said that global variables are basically put into what is essentially an instance of something like a "global object". So doing global.[variable] will pretty much equate to object.[variable] anyway.
 

TheouAegis

Member
If you're using a persistent object, I'd just keep it in the persistent object.

1) As BaBiA said, the global variables are handled by a global object (it was Mike, by the way).
2) Writing the variables to the global object requires redirecting the variables' addresses when writing.
3) Reading the variables in the controller object from the global object will be slower than the controller reading its own.
4) The other instances in the program won't care. lol
 

GMWolf

aka fel666
Having a general obj_game is about the worst hung you can do.
Break it up!

Have your score code in a score object,
You time code in a time object.
Etc etc.

It's about correctness, not speed (don't worry about speed, accessing variables is not where you should be optimizing).

Store your variables where they belong, not where they are fastest to access. (Again, won't make a difference anyways)
 
K

Kobold

Guest
If you're using a persistent object, I'd just keep it in the persistent object.

1) As BaBiA said, the global variables are handled by a global object (it was Mike, by the way).
2) Writing the variables to the global object requires redirecting the variables' addresses when writing.
3) Reading the variables in the controller object from the global object will be slower than the controller reading its own.
4) The other instances in the program won't care. lol
Now I am wondering about something...
Isn't there like one more check-off with a variable within an instance of a created active object?
Like with a global the compiler just checks for wether the global.variable exists... but with an object.variable it checks for two things:
1) Does the instance of the referenced object exist?
2) Does the variable within the referenced object exist?
...according to the compiler error message... I can create two errors on an uninitialized object.variable... but only one for a global.variable...
...that would mean involves more process, or not?

edit: ...I didn't include the data-format (real or string or array-boundary) checking.
 
L

Lonewolff

Guest
What I want to know is: which one would run faster?
Be faster to just choose one and move on.

This type of optimization will give no improvement in frame rate whatsoever. You are talking nanoseconds of difference, if anything. And the YYC will likely compile it to be the same code in the end anyway.
 

GMWolf

aka fel666
Well actually object.variable is not oy slower, but (more importantly) will lead to bugs, unmaintainable code and undefined behaviour.
Just don't do it.
Objects don't hold variables, instances do.
Just access you variables from the instance you created.
And if it's from a room, name your instance! (That's actually the fastest way to access variables.)
 
M

Matthew Hoinville

Guest
Having a general obj_game is about the worst hung you can do.
Break it up!

Have your score code in a score object,
You time code in a time object.
Etc etc.

It's about correctness, not speed (don't worry about speed, accessing variables is not where you should be optimizing).

Store your variables where they belong, not where they are fastest to access. (Again, won't make a difference anyways)
Really?
Things like score that affect the game in ways the player cares about I'd definitely put in separate objects, but I'm referring to more underlying system stuff
 

TheouAegis

Member
Dunno about with the YYC, but with the runner there's a lot of things that throw off numbers. But on average, after 20 million calls, the instance/object referencing was 13% of the CPU time vs. 10% for the global call with a margin of error of about 0.4%. Doing a simple microsecond count, the instance/object referencing was about 0.2 seconds (if I read that right) seconds slower. Sometimes it was about the same. All of these were for reads.

A variable write to a global is roughly the same as a variable write to an instance variable. On average, after 20 million calls, they were both at 12% of CPU time with the global read being 0.3% slower with a margin of error of 0.1%.

If for whatever reason you'd need to write to the controller object from the scope of any other object, it's to be expected that there would be roughly a difference of 1% and a profile check confirmed it was on average 13% for instance write vs. 12% for global write.


So yeah, it's a pretty negligible difference. Fel's warning holds merit, but for a controller object, it's like fretting over North Korea nuking the Olympic games this year.

As for objects, the fewer objects you're using, the better, but they need to stay within their scopes. The timer functions outside the scope of the player, so it shouldn't be in the player; however, the timer DOES function inside the same scope as the score -- they are both global scope. I definitely wouldn't be making one single object to modify the score and another single object to be modifying the timer. This ain't C++, this is GM and the more objects you have, the more bloated your program becomes.
 

GMWolf

aka fel666
So yeah, it's a pretty negligible difference. Fel's warning holds merit, but for a controller object, it's like fretting over North Korea nuking the Olympic games this year.
Do you know how many people here get bugs because they used object index instead of instances ?

As for objects, the fewer objects you're using, the better,
How? Just use the right number of objects for the job.

Instances are another story, adding one or two is ok, but adding a N can be a problem.

I definitely wouldn't be making one single object to modify the score and another single object to be modifying the timer.
I would.
That way it's easy to make a game mode where there is no timer, but there is a score.
Or one with a timer, but no score.
Or even one with both. Just create or destroy the relevant object.

(You can do much more too later but eh.. too long to explain).

GM and the more objects you have, the more bloated your program becomes.
Eh. Not really: it won't slow anything down or anything. It will just increase the number of objects in the resource tree.
 
K

Kobold

Guest
Quote: TheouAegis: "GM and the more objects you have, the more bloated your program becomes."

...Eh. Not really: it won't slow anything down or anything. It will just increase the number of objects in the resource tree.
If we're "increasing" numbers... there is obviously something contributing to a "more bloated" program or bundle of data which gets loaded into memory?...
....An added resource is a reservation of data, right?
 

GMWolf

aka fel666
If we're "increasing" numbers... there is obviously something contributing to a "more bloated" program or bundle of data which gets loaded into memory?...
....An added resource is a reservation of data, right?
it does NOT matter.
Seriously

It doesn't.
Write good code.
Efficiency comes with good data structures and algorithms. Not how you access a variable our the number of objects...
 

TheouAegis

Member
alarm x12
bbox_bottom
bbox_left
bbox_right
bbox_top
depth
direction
friction
gravity
gravity_direction
hspeed
id
image_alpha
image_angle
image_blend
image_index
image_number
image_single
image_speed
image_xscale
image_yscale
mask_index
object_index
path_endaction
path_index
path_orientation
path_position
path_positionprevious
path_scale
path_speed
persistent
solid
speed
sprite_height
sprite_index
sprite_width
sprite_xoffset
sprite_yoffset
timeline_index
timeline_position
timeline_speed
visible
vspeed
x
xprevious
xstart
y
yprevious
ystart


Okay, so you make 2 or 3 objects. Then what? Those objects won't do squat until you instantiate them. Then what? Each instance is going to add those variables into the RAM. So is your idea to just use a bunch of instance_change() calls every step of the way?
 

TheouAegis

Member
Do you know how many people here get bugs because they used object index instead of instances ?
The bugs people are getting from using object_index instead of instance id is because they have more than one instance of that object in the room. This and that are completely unrelated except on the chance that he accidentally double-clicked in the room editor and placed 2 or more instances of a controller object in the room; and even then it wouldn't matter because he'd only be needing one reference per read call anyway and that's exactly what he would get out of it.

Saving the id of the only instance in the room to a variable and then using that variable to reference the variables of that single instance would be slower still. So unless you're stupid enough to put two or more instances of an object which there is only supposed to be one of and can't figure out via debugging that you ****ed up along the way and put too many instances in the room, this is hardly an issue of concern.

We're talking about a controller object, not a player object or an NPC. It's no different than working with global and if GM actually gave us access to the global object so we could have global code run from the global object, then things could be sped up even more.
 

GMWolf

aka fel666
alarm x12
bbox_bottom
bbox_left
bbox_right
bbox_top
depth
direction
friction
gravity
gravity_direction
hspeed
id
image_alpha
image_angle
image_blend
image_index
image_number
image_single
image_speed
image_xscale
image_yscale
mask_index
object_index
path_endaction
path_index
path_orientation
path_position
path_positionprevious
path_scale
path_speed
persistent
solid
speed
sprite_height
sprite_index
sprite_width
sprite_xoffset
sprite_yoffset
timeline_index
timeline_position
timeline_speed
visible
vspeed
x
xprevious
xstart
y
yprevious
ystart


Okay, so you make 2 or 3 objects. Then what? Those objects won't do squat until you instantiate them. Then what? Each instance is going to add those variables into the RAM. So is your idea to just use a bunch of instance_change() calls every step of the way?
Let's say 10 extra instances (max) and 50 vars per.
Worst case scenario.
That's 500 variables. Each use 8 bytes.
That's 4kb.
Oh no! That's like a 32 by 32 sprite!
How will we ever cope with machines that have multiple gigabytes of memory available?

Don't even get me started on the idle cost of a few instances. It's wholely negligible next to rendering, game loop etc

What are you going to bring up next? The fact you cannot store data in contiguous memory?
Please...
 
Top