GameMaker gml_release_mode, ds_map

Azenris

Member
does gml_release_mode removed 'undefined' or slow it down in release?

Basically I want to know whether I can

Code:
var _temp = _map[? "moo" ];
if (_temp != undefined)
{
// do stuff with _temp
}
vs
Code:
if ( ds_map_exists( _map, "moo" )  )
{
var _temp = _map[? "moo" ];
// do stuff with _temp
}
Isn't the second one doing two map lookups everytime? I tried to search gml_release_mode
I saw at the bottom of this thread
"Checking for == undefined is pretty fast so long as you mind whether you intend to use gml_release_mode or not."
https://forum.yoyogames.com/index.php?threads/check-undefined-best-practice.53371/#post-325459

But did he mean its unuseable in release mode, or its slower, faster?


The GMS documentation says most error checking is removed, but I was unsure what that meant for maps and whether undefined is still a thing.

OR should I just go with the second code block and 2 map lookups each time?
 

GMWolf

aka fel666
Just from reading the docs, it seems like it should be faster under gml_release_mode, as fewer checks will be done. However, I dot know what those checks are.
It could be that the checks include type checking, then == undefined might not return the right values at all.
however is_undefined is an explicit type check, so that should always work.
best thing to do is write a couple tests to see if it works, and if its any faster.
 

FrostyCat

Redemption Seeker
Tested on 2.2.5.481:
Code:
gml_release_mode(true);

var map = ds_map_create();
map[? "goo"] = undefined;

// Non-existent key
if (map[? "foo"] == undefined) {
   show_message("foo1");
}
if (ds_map_exists(map, "foo")) {
   show_message("foo2");
}

// Key exists, but undefined value
if (map[? "goo"] == undefined) {
   show_message("goo1");
}
if (ds_map_exists(map, "goo")) {
   show_message("goo2");
}

ds_map_destroy(map);
I see foo1, goo1 and goo2.

So the undefined-returning behaviour is not part of the error-checking that gml_release_mode(true) turns off. But as the example above demonstrates, there is an exploitable difference between comparing to undefined and checking ds_map_exists(), so think over whether it applies to your project.
 

GMWolf

aka fel666
If this weren't GM, I would also say that a good optimizing compiler should fuse the two key lookups, but that's not necessarily true in c++ (depending on the map implementation) and possibly even less true in GM.
 

Azenris

Member
ty for the help guys.
Also, that was compiled with YYC FrostyCat?
I think/hope I won't ever put undefined as an input to a map to create that problem :D
I will definately still need ds_map_exists. It's just for certain things I wanted to avoid looking up twice.
 

Mool

Member
im pretty sure the release mode deactivates stuff like: YY_STACKTRACE_LINE(4);

Code:
void gml_Object_obj_gui_Alarm_0( CInstance* pSelf, CInstance* pOther )
{
YY_STACKTRACE_FUNC_ENTRY( "gml_Object_obj_gui_Alarm_0", 0 );
YYRValue obuiltin_id;


int ___w6244___ = (int)137;
SWithIterator ___wi6246___;
int ___wc6247___ = YYGML_NewWithIterator( &___wi6246___, (YYObjectBase**) &pSelf, (YYObjectBase**) &pOther, ___w6244___);
if (___wc6247___ > 0 ) {
do {

YY_STACKTRACE_LINE(4);

YY_STACKTRACE_LINE(5);
YYRValue* sself___ELEMENT__ = &((CInstanceBase*)pSelf)->GetYYVarRef(kVARID_self___ELEMENT__); /* set ContextID to sself___ELEMENT__ */
Variable_GetValue_Direct( (YYObjectBase*) pOther, g_VAR_id.val, (int)ARRAY_INDEX_NO_INDEX, &obuiltin_id );
(*sself___ELEMENT__)=/* First usage */obuiltin_id;

YY_STACKTRACE_LINE(6);
YYGML_event_user(pSelf,pOther,0);
} while(YYGML_WithIteratorNext( &___wi6246___, (YYObjectBase**) &pSelf, (YYObjectBase**) &pOther));
}
YYGML_DeleteWithIterator( &___wi6246___, (YYObjectBase**) &pSelf, (YYObjectBase**) &pOther);
}
 
Top