轮询下一个事件的延迟(如果在MacOS上可用)

轮询下一个事件的延迟(如果在MacOS上可用),macos,cocoa,latency,game-loop,peekmessage,Macos,Cocoa,Latency,Game Loop,Peekmessage,我正在尝试为MacOS编写一个简单的游戏循环。我在诸如GLFW、SDL和MacOS游戏端口等库中找到的DOOM、Quake和Handmade Hero的事件轮询解决方案是使用NextEventMachingmaskAPI。我对事件轮询的延迟感兴趣: 我运行的实验()包括打开Cocoa MacOS窗口并“随机”生成鼠标和键盘事件。在这样的实验中,我得到的前1000个事件的典型延迟数如下所示 请注意,前25%的延迟超过半毫秒。即使没有可用的事件(图表上的零),我们也可以获得超过一毫秒的延迟(参见第

我正在尝试为MacOS编写一个简单的游戏循环。我在诸如GLFW、SDL和MacOS游戏端口等库中找到的DOOM、Quake和Handmade Hero的事件轮询解决方案是使用
NextEventMachingmask
API。我对事件轮询的延迟感兴趣:

我运行的实验()包括打开Cocoa MacOS窗口并“随机”生成鼠标和键盘事件。在这样的实验中,我得到的前1000个事件的典型延迟数如下所示

请注意,前25%的延迟超过半毫秒。即使没有可用的事件(图表上的零),我们也可以获得超过一毫秒的延迟(参见第600个事件附近的零浮动)。更糟糕的是,这是我观察到的典型情况,当时我的Macbook没有太多的功能:只有一个终端和测试程序。当更多的应用程序运行时,情况会变得更糟

如果MacOS应用程序中有下一个(鼠标/键盘)事件,我想知道是否有更有效的方法来获取该事件。是否有一个技巧让
nexteventmachingmask
调用更有效

可以在此处找到运行此测试并生成类似于上面的绘图的源代码:

(更新)根据评论中提出的想法,我在没有任何鼠标/键盘移动的情况下运行了测试。以下是延迟百分比:

# latency without any keyboard/mouse event in milliseconds
:         0%          5%         10%         15%         20%         25%
: 0.04029500  0.07617675  0.07908070  0.08556100  0.10188940  0.12956500
:        30%         35%         40%         45%         50%         55%
: 0.13832200  0.14023150  0.14802140  0.15003550  0.15045250  0.15088950
:        60%         65%         70%         75%         80%         85%
: 0.15125000  0.15162535  0.15190300  0.15235550  0.15313200  0.15972645
:        90%         95%        100%
: 0.16802250  0.21194335 35.93352900
等待.15毫秒以发现没有生成任何事件的想法感觉不正确

(更新2)刚刚对ubuntu上运行的所有
SDL\u EventPoll
MessagePump
调用进行了计时,我得到的延迟分布看起来好多了:

 #       0%         5%        10%        15%        20%        25%        30%
 :0.00095100 0.00186075 0.00215500 0.00226400 0.00234180 0.00241500 0.00255900
 :       35%        40%        45%        50%        55%        60%        65%
 :0.00289495 0.00652280 0.00712510 0.00749900 0.00770290 0.00807660 0.00888870
 :       70%        75%        80%        85%        90%        95%       100%
 :0.00897200 0.00905000 0.00931060 0.01374225 0.01728800 0.03256290 0.23016000

而在MacOS上,gzdoom也在与
nextEventMatchingMask
(数百微秒的延迟数)的慢度作斗争。结论:不仅是我的测试代码在MacOS上获取下一个键盘/鼠标事件的速度很慢。

您可以通过缓存
IMP
nexteventmachingmask:untilDate:inMode:dequeue:
方法并直接调用该方法来弥补一点额外的性能,消除
objc\u msgSend
调用。您可能希望使用自定义运行循环模式(只是系统框架不太可能使用的字符串),而不是
NSDefaultRunLoopMode
。后者允许其他输入源和定时器触发。并且,为了确保这一点,请查看是否有影响。尝试将掩码设置为您关心的事件?更新测试以屏蔽感兴趣的事件,设置自定义运行循环模式,并禁用AppNap。延迟分布似乎在相同的范围内。我的预期可能与此不符,但我预期延迟会小得多。我在考虑windows()上的
PeekMessage
API调用。我显示了在
nextEventMachingeEventTask:until:Date:inMode:dequeue
中总共花费了119ms,当时我没有按那么多键,而是单击并移动鼠标。如果我没有执行任何事件(没有鼠标移动、单击或键盘活动),我会看到:
# latency without any keyboard/mouse event in milliseconds
:         0%          5%         10%         15%         20%         25%
: 0.04029500  0.07617675  0.07908070  0.08556100  0.10188940  0.12956500
:        30%         35%         40%         45%         50%         55%
: 0.13832200  0.14023150  0.14802140  0.15003550  0.15045250  0.15088950
:        60%         65%         70%         75%         80%         85%
: 0.15125000  0.15162535  0.15190300  0.15235550  0.15313200  0.15972645
:        90%         95%        100%
: 0.16802250  0.21194335 35.93352900
 #       0%         5%        10%        15%        20%        25%        30%
 :0.00095100 0.00186075 0.00215500 0.00226400 0.00234180 0.00241500 0.00255900
 :       35%        40%        45%        50%        55%        60%        65%
 :0.00289495 0.00652280 0.00712510 0.00749900 0.00770290 0.00807660 0.00888870
 :       70%        75%        80%        85%        90%        95%       100%
 :0.00897200 0.00905000 0.00931060 0.01374225 0.01728800 0.03256290 0.23016000