System Key Timers 2

Akolyt0r

New Member
Reaction score
33
OK, maybe Keytimers is useful for some special cases ...

But you really should add more details to your first post / comments in the trigger itself...

Especially about the accuracy problems especially with higher periods ....(thats a CRUCIAL Issue ..aswell as the limit of 20 different periods, but you already mentioned that)

You should also tell people that for most cases TimerUtils (Red,Purple,Blue) are the best system to choose...

You might aswell tell the people that your benchmark is clearly better for KeyTimers (which shows that KeyTimers is faster for special cases ..with lots of similar periods) ...but in most cases (more different periods) it wouldnt.
 

Jesus4Lyf

Good Idea™
Reaction score
397
But you really should add more details to your first post / comments in the trigger itself...

Especially about the accuracy problems especially with higher periods ....
Although the problem has been misstated again it seems that isn't in the cons and should be. Cheers. :)
Will add that next version.

You should also tell people that for most cases TimerUtils (Red,Purple,Blue) are the best system to choose...
I can't agree with that. KT1 is easily the best system. KT2 is a nice interface for KT1 and is faster than TU, and TU is brilliant for exactly what I've said in section 5 (which is a specific case).

shows that KeyTimers is faster for special cases ..with lots of similar periods
I'd say that's "most cases", not the contrary. Especially in writing spells. Obviously this is up for debate.

But think about this... If the periods are that different, then they're going to be greater than 1 second. If they're greater than 1 second, who cares about speed. If they're in the range that speed matters at all (less than 0.5 seconds?) then KT2 will likely be faster because the period will probably be the same. But my guess is even with different periods, the speed drop would be splitting hairs. Look at what the difference would be: a few array calls. I'll try to benchtest this sometime, it will take some thinking, but I think people have been overstating it. :)

Still, thanks for your input. I'll try to test your claims soon. :D
 

emjlr3

Change can be a good thing
Reaction score
395
using one timer for >1s intervals is silly anyway
 

Akolyt0r

New Member
Reaction score
33
i would rather say 0.5 seconds ...for most cases ...
so you should definetly recommend TU or something equivalent for higher periods...
 

Jesus4Lyf

Good Idea™
Reaction score
397
Why would you use a repeating timer, declared mid game, for a high period anyway (>2 seconds)?

>using one timer for >1s intervals is silly anyway
Lol, TriggerSleepAction?

>recommend TU or something equivalent for higher periods...
You know I already have in the document, right? But not for higher periods, I've explained it better than that, because that's not the problem.

>for higher periods...
My problem in ruling out KT for "high" periods is I use it all the time for 1 sec and 0.5 sec... Like 1 sec for AI or 0.5 sec for damage over time effects... The problem isn't the high period, the problem is needing the first execution to be exactly after the period has passed, from calling "Add".

I really hope this issue is done with. Haven't been talking about anything but the first execution issue for about 7 posts now. :banghead:

As said, I intend to add it to the cons next version. :)
 

emjlr3

Change can be a good thing
Reaction score
395
what I meant is looping through tons of stuff on a >1s interval is silly, just use 1 timer/instance - the performance hit is negligable considering the interval length, and trying to sync them up is goofy
 

Cohadar

master of fugue
Reaction score
209
Vex was mostly complaining on stuff he should not be because KT2 clearly states:
JASS:

//      =Cons=
//               - Periods should only be taken to 0.005 of a second, not 0.007 for example.
//               - Limit of 20 different periods.
//               - Limit of 400 instances of each period.
//               - Period can't be above 40.955 seconds.


But he is right about one thing, KT2 has too many limits to be used as general purpose system (too many stuff can go wrong if someone does not know the details)
And the point of any good systems is to be idiot-proof.

How it works:
KT2 is using attaching method that adds index to timer by applying a small modification to it's period.
For example if you wanted to attach index 71 to 0.05 timer you would create a 0.050071 sec timer.
the 0.000071 modification is too small to be noticed and can be extract back as index with some simple math. (check system code for details)

The downsides of this are already mentioned and they are caused by inprecise real number arithmetic.

KT2 is a valiant effort but sadly has too many cons to be usable.

PS:
JASS:

//               - Key Timers only uses one timer per period to keep things efficient,
//                 especially in attaching data.

This is not possible to do without errors for timers with periods greater than 0.1 sec (I already explained that in detail in ABCT thread I think)
 

Jesus4Lyf

Good Idea™
Reaction score
397
Vex was mostly complaining on stuff he should not be because KT2 clearly states:
JASS:

//      =Cons=
//               - Periods should only be taken to 0.005 of a second, not 0.007 for example.
//               - Limit of 20 different periods.
//               - Limit of 400 instances of each period.
//               - Period can't be above 40.955 seconds.
I agree with you there. But...
How it works:
KT2 is using attaching method that adds index to timer by applying a small modification to it's period.
For example if you wanted to attach index 71 to 0.05 timer you would create a 0.050071 sec timer.
the 0.000071 modification is too small to be noticed and can be extract back as index with some simple math. (check system code for details)
You're wrong. In fact, that doesn't even make sense for a multi-instancing timer system. :p

Hey, good to see you in this thread again, though...

And actually I consider this system quite stable and fairly idiot proof. :)

Hell, I could just make a debug version if idiot-proofing is that important! :D Or add the debug commands like on TT...

Edit:
I'm very excited. Next version should only have:
JASS:

//      =Cons=
//               - Periods should only be taken to 0.005 of a second, not 0.007 for example.
//               - Period can't be above 40.955 seconds.
//               - Cannot have more than 8191 instances at once.

That's right. I've removed the 400 instances/period and 20 period limits. :D
It took some doing. o.o

I've also added the 0.005 safety, as talked about before. I'll release the code tomorrow, once it's optimized a bit. :)

That should make this system more stable and noob friendly. Oh, and I think it may also be more efficient; yet to benchtest. :D

And yes, you'll be able to simply upgrade by copying the new version over the old. :)

So uhh... This should solve the problem of "Noobs may forget the constraints, and it's technically possible to go over accidentally!"... If that's what you call a problem. :)

Edit: And just to reassure everyone, unlike what Cohadar said, the exact period you enter is used, taken to an accuracy of 0.005. It's now also extra stable. That is, when I release the code tomorrow. :)
 

Cohadar

master of fugue
Reaction score
209
Edit: And just to reassure everyone, unlike what Cohadar said, the exact period you enter is used, taken to an accuracy of 0.005.

We could debate on this but I don't see the point if new version is coming.
So I will simply wait for you. (in ambush :D)
 

Jesus4Lyf

Good Idea™
Reaction score
397
We could debate on this but I don't see the point if new version is coming.
Well actually, we really can't...
public function Add takes code func, integer attachment, real period returns nothing
...
if maxp+399==p*400 then
call TimerStart(KeyTimer[p],period,true,function KeyTimerLoop)
endif
endfunction
You're wrong. It jammed exactly what the user put in into the period. :)

If users didn't follow the 0.005 accuracy rule, it was technically possible for the period to be out by up to 0.005 (if you understand the code, you'll know why).

The new version will still use the same method for attaching to the timers, by the way. That's why I bothered to clarify.

Edit: Yay! Released KT2 version 1.3. The speed is within margin of error to version 1.1, but an estimated 0.2% efficiency gain... The "Add" function should be faster too, I think, but I haven't bench tested this. It no longer has the 400 instances per period and 20 different period limits. I believe all of what Vexorian has said has been absorbed into the system and/or documentation, now. :)

Although I have tested this quite thoroughly, please report any bugs... Shouldn't be any. My test is implementing the Sandman spell with the new version, and multi-instancing it. :D

Anyway, I also updated Sharl and Sandman to use KT2 version 1.3. :D
 

Cohadar

master of fugue
Reaction score
209
You're wrong. It jammed exactly what the user put in into the period. :)
I assumed you used the same stuff as old methods that did TimerGetTimeout() so yes I was wrong, sorry.

But still..

Like I said this is impossible:
JASS:

//		 - Key Timers only uses one timer per period to keep things efficient,
//		   especially in attaching and retrieving data.


because as you say yourself:
JASS:
//		 - The first procurement of an instance is random between 0.0 seconds and the period
//		   (Doesn't effect periods less than 0.100 seconds).


And some questions:

1. Why isn't 200.0 a constant?
JASS:

		private constant real RESOLUTION = 200.0 // must be real not integer


2. Why are you using double-linked lists when single-linked list + pivot pointer would do the job?

3. Why the frak you don't have a security mechanism in Add function?
This one for example:
JASS:
	
public function Add takes code func, integer data, real period returns nothing
    set a_id=R2I(period*RESOLUTION)
    if ((a_id/RESOLUTION) != period) or (a_id<0) or (a_id>8190) then
        call BJDebugMsg("ERROR: KT_Add - Invalid period: "+ R2S(period))
        return
    endif
    // continue...
endfunction


4.
The speed is within margin of error to version 1.1, but an estimated 0.2% efficiency gain...
Does your estimation technique consist of using a combination of magic mushrooms, old bones and chicken blood?

5. And last and the most important:
Why are you trying to push this sys to be something it is not?

The attaching technique you use cannot and never will be good for low-frequency timers. The plain fact is that it is both more efficient and more precise to use one timer per instance on greater periods so why not simply limit KT to periods below 1 sec?

That way you can even increase resolution to 8000 which would get you much better period coverage.
You don't even have to go that far,
a resolution of 800 would be enough to cover a 0.03125 period (my personal favourite)

TIP: Since all numbers in jass are either hex or decimal it is best to use a resolution in form of (2^n * 5^m) where n>=m
 

Jesus4Lyf

Good Idea™
Reaction score
397
Aww c'mon... Aren't you gonna say that you're impressed with my initiative or something nice? XD

I assumed you used the same stuff as old methods that did TimerGetTimeout() so yes I was wrong, sorry.
I thought I was the only one. o_O
I mean, surely H2I is faster than attaching the way you described, and any other type of system can't use my method here. So I thought being the only one was a reasonable conclusion. XD

Yay, questions time!

1. Why isn't 200.0 a constant?
Thought about it, but if people write spells using KT2, and someone messes with that value in the wrong way, the spells will break. I'd rather make some sort of standard. I like 0.03125 though. I'll consider knocking down the value, but generally intend to leave it hard coded. If people want to screw with it, it's not hard anyway; but I wouldn't want to encourage it for the purpose of shared spells on TheHelper and such. :)

2. Why are you using double-linked lists when single-linked list + pivot pointer would do the job?
I assume by pivot pointer you mean store the previous in the loop...
And you're right. It does the job. But I already considered this - it's less efficient in the loop! Think about it. :)

3. Why the frak you don't have a security mechanism in Add function?
Haha... Was wondering when that would come up. Actually, it's already come up in this thread. Actually, there already is half a security function - it uses id/200.0 instead of period. XD
But you're right. I'll consider adding that with the appropriate debug clauses.

4. Does your estimation technique consist of using a combination of magic mushrooms, old bones and chicken blood?
Hahaha... A reasonable question for someone who hasn't read my documentation :p. It's the same efficiency test I used to compare timer systems. KT2 version 1.1 scored 31,850 executions per second, and KT2 version 1.3 scored 31,900. But of course, this is within margin of error (which is about 200 the way I do it).

5. And last and the most important:
Why are you trying to push this sys to be something it is not?
Yeah, agreed about your actual points (but I'm not pushing it to be something it isn't, check the documentation; I recommend TU Red for high frequencies or whatever). However, I use this system for 1 second periods all the time. For AI and camera systems. :)
A high period does mean the first procurement will be inaccurate, but it doesn't mean it will matter. Instead, I just inform everyone accurately of the issue (instead of drawing that conclusion for them). I doubt you can disagree that I do that.

TIP: Since all numbers in jass are either hex or decimal it is best to use a resolution in form of (2^n * 5^m) where n>=m
Yep, you lost me there. I can only assume 8's and 0's are good things for unknown reasons. XD
Maybe one day I'll research this. <_<

Hey, thanks for the response. I've been eagerly awaiting it. :D XD

By the way, I'm actually considering totally removing the "RESOLUTION" as you called it. Because I can just use hashing or gamecache to remove the last two restrictions. :p

Of course, sadly this comes at a mild efficiency sacrifice... =/
But if I made it hash over a resolution of about 800 it probably wouldn't! :p
And then I could make the resoluton a constant. :)

JASS:
...
set t_id=R2I(GetPeriod*800.0) mod 8000
loop
exitwhen KeyTimer[t_id]==GetExpiredTimer()
set t_id=t_id+1
endloop
...


Is this worth implementing?

Edit: Yeah. I think so. :)
Note to self: Implement safety, too.
Edit: Wait... I won't need safety. XD
 

Cohadar

master of fugue
Reaction score
209
Aww c'mon... Aren't you gonna say that you're impressed with my initiative or something nice? XD
No. :D
but maybe I am.
nah :p

Hahaha... A reasonable question for someone who hasn't read my documentation :p. It's the same efficiency test I used to compare timer systems.
So it is old fashioned bat wings, pig guts and snake eggs combination after all.

I recommend TU Red for high frequencies or whatever).
TimerUtils is just ABC with bad syntax.

Of course, sadly this comes at a mild efficiency sacrifice... =/
I have yet to see a wc3 map that suffers more from efficiency issues than from sucking issues.

JASS:
...
set t_id=R2I(GetPeriod*800.0) mod 8000
loop
exitwhen KeyTimer[t_id]==GetExpiredTimer()
set t_id=t_id+1
endloop
...


Why the mod?
 

Jesus4Lyf

Good Idea™
Reaction score
397
Aw.
I have yet to see a wc3 map that suffers more from efficiency issues than from sucking issues.
QFT. <_<
Then again, DotA (debatable, but you get my point).
Why the mod?
So you can have periods of over 9,000! (Seconds.)
More to the point, so I don't have to put "Limited to periods of up to 10" in the cons. :p
Then people could change the resolution to 8000 without breaking the system at all.
 

Cohadar

master of fugue
Reaction score
209
So you can have periods of over 9,000! (Seconds.)
More to the point, so I don't have to put "Limited to periods of up to 10" in the cons. :p
Then people could change the resolution to 8000 without breaking the system at all.

you do realize that periods of 5 seconds and 8005 seconds would end up on the same timer if you use the mod?
 

Cohadar

master of fugue
Reaction score
209
Read it carefully. It iterates from there until it finds the correct timer. I'd probably compare on period instead, though. :)

Ah yes silly me, you did mention hashing.

Why not just forbid silly periods like 0.05177?
I mean if some deranged mind needs something like that he can use some other sys.
 
General chit-chat
Help Users
  • No one is chatting at the moment.

      The Helper Discord

      Members online

      Affiliates

      Hive Workshop NUON Dome World Editor Tutorials

      Network Sponsors

      Apex Steel Pipe - Buys and sells Steel Pipe.
      Top