Jump to content
Rocketrolf

What is faster? .hpp or sqf

Recommended Posts

Correct, the simple concept someone here fails to understand even if his life depended on it.

 

Yep, those who don't know should be practicing more and not spewing incorrect information as fact. How long has the scripting community been around? Let alone your expertise, Killzone. I'm sure if there's a better way to do things or some "silver bullet" trick, it would have been discovered already and likely announced by Bohemia. Again, as I've already stated, performance gains would better be achieved through optimization of algorithms, not by hackish tinkering. The root problem is someone's method of doing something isn't as efficient as it could be. Fix the root issue, don't just apply a bandaid.

 

So far I've seen so much terminology misused and concepts entirely asinine in this thread that it's even hard for me to make any sense out of it all.

Share this post


Link to post
Share on other sites

 

Satisfied now?

Not in the slightest. I dont care about your times, where is code for execVM?

  • Like 1

Share this post


Link to post
Share on other sites

Not in the slightest. I dont care about your times, where is code for execVM?

 

The fact that this wasn't provided and overlooked removes all validity of the claims.

A lack of understanding of execVM and spawn shouldn't be followed by why those shouldn't be used...

Share this post


Link to post
Share on other sites

Show us how it's done then? 

Lets see if you can understand this:

 

testCode = {a = [1,2,3,4,5,6,7,8,9,0]};
currentScripts = count diag_activeSQFScripts;
startTime = diag_tickTime;
for "_i" from 1 to 10000 do {0 spawn testCode}; 
addMissionEventHandler ["EachFrame", 
{
	if (count diag_activeSQFScripts <= currentScripts) then 
	{
		hint str ((diag_tickTime - startTime) / 10);
		removeAllMissionEventHandlers "EachFrame";
	};
}]; 
  • Like 1

Share this post


Link to post
Share on other sites

Alright whatever.

At one point KK I looked up to you now I don't.

You are always condescending. Poor role model if you ask me.

I'll take my leave and let the "experts" take over. I don't have the time or the patience to deal with this anymore.
I really do not. . Enjoy your...
Circlejerk.

Good bye.

  • Like 1

Share this post


Link to post
Share on other sites

Hey child,

just calm down.

KK is just straight with criticizing people which disseminate wrong information. I think he has the standing to do so...

 

Cheers...

  • Like 1

Share this post


Link to post
Share on other sites

No need to be arguing and insulting each other, we're all here to learn and share.  :wub:

  • Like 2

Share this post


Link to post
Share on other sites

I'll take my leave and let the "experts" take over.

I like how you put "experts" in quotes, to imply that there is only one true expert here, and he is leaving now, beaten but not defeated! Well, see you back soon.

  • Like 1

Share this post


Link to post
Share on other sites

I apologise for what I said before.

Can you explain why this works?
 

testCode = {a = [1,2,3,4,5,6,7,8,9,0]};
currentScripts = count diag_activeSQFScripts;
startTime = diag_tickTime;
for "_i" from 1 to 10000 do {0 spawn testCode};
addMissionEventHandler ["EachFrame", 
{
    if (count diag_activeSQFScripts <= currentScripts) then
    {
        hint str ((diag_tickTime - startTime) / 10);
        removeAllMissionEventHandlers "EachFrame";
    };
}];

vs my method I thought the "Performance check button" utilised diag_codePerformance command? Not BIS_fnc_codePerformance anymore?

 

But as far as the searching of a config-file goes that performance was a correct measure?

Share this post


Link to post
Share on other sites

 This all started with discussion about speed of returning predefined values, why not keep the test as simple as possible?

 

Mission setup

init.sqf:

myDataVSimple = ["a","b","c","d","e","f","g","h","i","j","k","l","m","n"];
myDataVNested = [[[["a","b","c","d","e","f","g","h","i","j","k","l","m","n"]]]];

description.ext:

myDataCSimple[] = {"a","b","c","d","e","f","g","h","i","j","k","l","m","n"};
class superClass
{
  class parentClass
  {
    class childClass
    {
      myDataCNested[] = {"a","b","c","d","e","f","g","h","i","j","k","l","m","n"};
    };
  };
};

In mission:
_foo = myDataV select 0; //0.0009ms
_foo = myDataV select 0 select 0 select 0 select 0; //0.0014ms

_foo = getArray (missionConfigFile >> "myDataCSimple") select 0; //0.0023 ms

_foo = getArray (missionConfigFile >> "superClass" >> "parentClass" >> "childclass" >> "myDataCNested") select 0; //0.0033 ms

Share this post


Link to post
Share on other sites

So the performance difference is practically inconceivable.

Share this post


Link to post
Share on other sites

So the performance difference is practically inconceivable.

 

For a single use, yes.

However, for a scripted system that uses a lot of predefined data, loading the data into global variables will perform better than storing it in config.

  • Like 1

Share this post


Link to post
Share on other sites

Makes sense. Keep the data cached in memory for quick recall.

Share this post


Link to post
Share on other sites

I apologise for what I said before.

Can you explain why this works?

 

You cannot measure how long it takes to execute scheduled code with diag_codePerformance (or BIS_fnc_codePerformance, same) because they designed to run given code in unscheduled environment. So you cannot simply waituntil...it is finished. As spawn page explains, spawn CODE does not execute CODE immediately, but loads the CODE into scheduler and returns. So if you just diag_codePerformance [{spawn CODE}]  you will be measuring how long it takes to load CODE in scheduler.

When CODE is loaded in the scheduler it is given handle and you can see how many of them are currently in the scheduler with diag_activeSQFScripts. So when you spawn 10000 CODEs you will have roughly 10000 long array returned by diag_activeSQFScripts, and as scheduler goes through them, they will disappear from array until it is []. So when this happen you know this is when all CODEs completed. Then it is easy to calculate average time.

  • Like 3
  • Thanks 1

Share this post


Link to post
Share on other sites

 This all started with discussion about speed of returning predefined values, why not keep the test as simple as possible?

 

Mission setup

init.sqf:

myDataVSimple = ["a","b","c","d","e","f","g","h","i","j","k","l","m","n"];
myDataVNested = [[[["a","b","c","d","e","f","g","h","i","j","k","l","m","n"]]]];

description.ext:

myDataCSimple[] = {"a","b","c","d","e","f","g","h","i","j","k","l","m","n"};
class superClass
{
  class parentClass
  {
    class childClass
    {
      myDataCNested[] = {"a","b","c","d","e","f","g","h","i","j","k","l","m","n"};
    };
  };
};

In mission:

_foo = myDataV select 0; //0.0009ms

_foo = myDataV select 0 select 0 select 0 select 0; //0.0014ms

_foo = getArray (missionConfigFile >> "myDataCSimple") select 0; //0.0023 ms

_foo = getArray (missionConfigFile >> "superClass" >> "parentClass" >> "childclass" >> "myDataCNested") select 0; //0.0033 ms

 

The equivalent of myDataVNested in config would be

myDataCNested[] = {{{{"a","b","c","d","e","f","g","h","i","j","k","l","m","n"}}}};

The fastest way to get it would be 

 

getMissionConfigValue "myDataCNested"

You can compare it if you want to make sure it is the same:

 

myDataVNested = [[[["a","b","c","d","e","f","g","h","i","j","k","l","m","n"]]]];
myDataCNested = getMissionConfigValue "myDataCNested";
hint str (myDataVNested isEqualTo myDataCNested); //true

myDataVNested is still faster.

Share this post


Link to post
Share on other sites

Neat. I now understand what you mean by the scheduler now, but isn't it true there is always something in the scheduler when a mission is running? I mean I noticed every damn vehicle with a clock adds to that script count. Thats why you can't measure them using the scheduler. I see now because it will not provide an accurate time stamp purely because of the scheduler suspending / restarting every so often?

Share this post


Link to post
Share on other sites

Thats why you can't measure them using the scheduler

Eh? Measure what? How do you measure something using scheduler? Sorry you make no sense as usual.

  • Like 1

Share this post


Link to post
Share on other sites
player globalChat (format ["%1 Thats why you can't %2 them using the %3.", call GetFillerText, call GetRandomVerb, call GetRandomTerminology]);

Please stop talking about things you have no clue about.

  • Like 1

Share this post


Link to post
Share on other sites
player globalChat (format ["%1 Thats why you can't %2 them using the %3.", call GetFillerText, call GetRandomVerb, call GetRandomTerminology]);

That would make a splendid forum troll AI script. I have to suggest this to Dwarden.

  • Like 1

Share this post


Link to post
Share on other sites

The root problem is someone's method of doing something isn't as efficient as it could be. Fix the root issue, don't just apply a bandaid.

 

 

But its a really really fast bandaid :)

Share this post


Link to post
Share on other sites

I have no idea why i received a notification for this thread today, which was from way back last year but I did

Shameful thread replies from some of you.

I didn't read all of it so might not have grasped the full story.

 

From what I can gather from your question.

Basically anything #included from the description.ext or any config file in any addon is run before anything else so it doesn't make any difference to performance of the mission other than load time of the mission which unless its thousands and thousands of lines of config will be insignificant.

 All this code is run before even 'preinit' code. Well before the mission starts, before the mission.sqm, before any preinit code.

 

 

You can actually #include anything.***  .hpp .h or.someweirdextensionname so its not the extension you use but where it is called from that defines how it is run

 

.sqf speed depends on the quality of the code and whether is is precompiled once and saved into memory as a function before it is called or whether is is run say from the init.sqf tree where is is compiled and run every time it is called.

Is there a difference between spawning a precompiled function (Useful if that function has a sleep command)  or calling? (I dont know)

 

 

EDIT. I just realised i replied earlier in this thread on page 2

Share this post


Link to post
Share on other sites

Please sign in to comment

You will be able to leave a comment after signing in



Sign In Now

×