Uvloop in HA?

Hi,

I was wondering why HA uses the standard asyncio loop when uvloop is much faster? It does support musl (i.e. for docker).

Running the HA benchmarks gave impressive speed gains. I know runner.py has it’s own event loop policy, but it looks like it just has additional stuff on top of the standard event loop and it calls super() to do most of the actual loop stuff.

I’ve implemented this, here are my benchmarks:

standard loop:

python -m homeassistant --script benchmark fire_events 
Using event loop: _UnixSelectorEventLoop
Benchmark fire_events done in 0.5234766029752791s
Benchmark fire_events done in 0.5671124220825732s
Benchmark fire_events done in 0.5437433668412268s
Benchmark fire_events done in 0.566884689964354s
Benchmark fire_events done in 0.5544873801991343s

python -m homeassistant --script benchmark fire_events_with_filter
Using event loop: _UnixSelectorEventLoop
Benchmark fire_events_with_filter done in 4.6570785343647e-05s
Benchmark fire_events_with_filter done in 4.39411960542202e-05s
Benchmark fire_events_with_filter done in 4.432490095496178e-05s
Benchmark fire_events_with_filter done in 4.2168889194726944e-05s
Benchmark fire_events_with_filter done in 4.406040534377098e-05s

python -m homeassistant --script benchmark state_changed_helper
Using event loop: _UnixSelectorEventLoop
Benchmark state_changed_helper done in 1.7030216148123145s
Benchmark state_changed_helper done in 1.7130365730263293s
Benchmark state_changed_helper done in 1.7361900368705392s
Benchmark state_changed_helper done in 1.767208834644407s
Benchmark state_changed_helper done in 1.7111733444035053s

python -m homeassistant --script benchmark state_changed_event_helper
Using event loop: _UnixSelectorEventLoop
Benchmark state_changed_event_helper done in 0.9205999942496419s
Benchmark state_changed_event_helper done in 0.9951977380551398s
Benchmark state_changed_event_helper done in 1.0259310542605817s
Benchmark state_changed_event_helper done in 0.9986911937594414s
Benchmark state_changed_event_helper done in 1.0097629642114043s


python -m homeassistant --script benchmark state_changed_event_filter_helper
Using event loop: _UnixSelectorEventLoop
Benchmark state_changed_event_filter_helper done in 8.184323087334633e-05s
Benchmark state_changed_event_filter_helper done in 4.694890230894089e-05s
Benchmark state_changed_event_filter_helper done in 4.674308001995087e-05s
Benchmark state_changed_event_filter_helper done in 4.785088822245598e-05s
Benchmark state_changed_event_filter_helper done in 4.3750274926424026e-05s

python -m homeassistant --script benchmark filtering_entity_id
Using event loop: _UnixSelectorEventLoop
Benchmark filtering_entity_id done in 0.06939946999773383s
Benchmark filtering_entity_id done in 0.0723396330140531s
Benchmark filtering_entity_id done in 0.07890871400013566s
Benchmark filtering_entity_id done in 0.07536242995411158s
Benchmark filtering_entity_id done in 0.07204410014674067s
Benchmark filtering_entity_id done in 0.07569080591201782s
Benchmark filtering_entity_id done in 0.07275245990604162s
Benchmark filtering_entity_id done in 0.07671137806028128s
Benchmark filtering_entity_id done in 0.07493564207106829s
Benchmark filtering_entity_id done in 0.06282419618219137s

python -m homeassistant --script benchmark valid_entity_id
Using event loop: _UnixSelectorEventLoop
Benchmark valid_entity_id done in 0.48626730404794216s
Benchmark valid_entity_id done in 0.5101926913484931s
Benchmark valid_entity_id done in 0.5250345272943377s
Benchmark valid_entity_id done in 0.5192310679703951s
Benchmark valid_entity_id done in 0.5294804931618273s
Benchmark valid_entity_id done in 0.5243523600511253s

python -m homeassistant --script benchmark json_serialize_states
Using event loop: _UnixSelectorEventLoop
Benchmark json_serialize_states done in 4.096706085372716s
Benchmark json_serialize_states done in 4.074889219831675s
Benchmark json_serialize_states done in 4.384049125015736s
Benchmark json_serialize_states done in 4.038291460834444s
Benchmark json_serialize_states done in 4.012825920712203s

uvloop benchmarks:

python -m homeassistant --script benchmark fire_events 
Using event loop: uvloop
Benchmark fire_events done in 0.19919736124575138s
Benchmark fire_events done in 0.21901592565700412s
Benchmark fire_events done in 0.3783682808279991s
Benchmark fire_events done in 0.2537013040855527s
Benchmark fire_events done in 0.21188035933300853s

python -m homeassistant --script benchmark fire_events_with_filter
Using event loop: uvloop
Benchmark fire_events_with_filter done in 4.319380968809128e-05s
Benchmark fire_events_with_filter done in 4.3459702283144e-05s
Benchmark fire_events_with_filter done in 4.309928044676781e-05s
Benchmark fire_events_with_filter done in 4.447903484106064e-05s
Benchmark fire_events_with_filter done in 4.3818727135658264e-05s

python -m homeassistant --script benchmark state_changed_helper
Using event loop: uvloop
Benchmark state_changed_helper done in 1.5188445281237364s
Benchmark state_changed_helper done in 1.5958181601017714s
Benchmark state_changed_helper done in 1.5132463960908353s
Benchmark state_changed_helper done in 1.5610447311773896s
Benchmark state_changed_helper done in 1.5299833500757813s

python -m homeassistant --script benchmark state_changed_event_helper
Using event loop: uvloop
Benchmark state_changed_event_helper done in 0.6498983497731388s
Benchmark state_changed_event_helper done in 0.7006727429106832s
Benchmark state_changed_event_helper done in 0.691945091355592s
Benchmark state_changed_event_helper done in 0.6733607463538647s
Benchmark state_changed_event_helper done in 0.6823208746500313s

python -m homeassistant --script benchmark state_changed_event_filter_helper
Using event loop: uvloop
Benchmark state_changed_event_filter_helper done in 4.5069027692079544e-05s
Benchmark state_changed_event_filter_helper done in 5.119387060403824e-05s
Benchmark state_changed_event_filter_helper done in 4.437798634171486e-05s
Benchmark state_changed_event_filter_helper done in 4.577077925205231e-05s
Benchmark state_changed_event_filter_helper done in 4.696007817983627e-05s

python -m homeassistant --script benchmark filtering_entity_id
Using event loop: uvloop
Benchmark filtering_entity_id done in 0.06272861594334245s
Benchmark filtering_entity_id done in 0.06284308712929487s
Benchmark filtering_entity_id done in 0.06238045124337077s
Benchmark filtering_entity_id done in 0.05800309497863054s
Benchmark filtering_entity_id done in 0.05756722204387188s
Benchmark filtering_entity_id done in 0.06107477191835642s
Benchmark filtering_entity_id done in 0.0572995119728148s
Benchmark filtering_entity_id done in 0.05675503285601735s

python -m homeassistant --script benchmark valid_entity_id
Using event loop: uvloop
Benchmark valid_entity_id done in 0.5022582369856536s
Benchmark valid_entity_id done in 0.4344895160757005s
Benchmark valid_entity_id done in 0.44352875696495175s
Benchmark valid_entity_id done in 0.46541520999744534s
Benchmark valid_entity_id done in 0.45438246289268136s
Benchmark valid_entity_id done in 0.46582747297361493s
Benchmark valid_entity_id done in 0.4742277101613581s
Benchmark valid_entity_id done in 0.4535853983834386s

python -m homeassistant --script benchmark json_serialize_states
Using event loop: uvloop
Benchmark json_serialize_states done in 4.206879341043532s
Benchmark json_serialize_states done in 4.249316385015845s
Benchmark json_serialize_states done in 4.24672843888402s
Benchmark json_serialize_states done in 4.2714570560492575s
Benchmark json_serialize_states done in 4.26232343679294s