feat: optimizing sending answers to questions (#1227) · python-zeroconf/python-zeroconf@cd7b56b

Original file line numberDiff line numberDiff line change

@@ -23,6 +23,7 @@

2323

import itertools

2424

import random

2525

from collections import deque

26+

from operator import attrgetter

2627

from typing import (

2728

TYPE_CHECKING,

2829

Dict,

@@ -71,6 +72,8 @@

7172

_MULTICAST_DELAY_RANDOM_INTERVAL = (20, 120)

7273

_RESPOND_IMMEDIATE_TYPES = {_TYPE_NSEC, _TYPE_SRV, *_ADDRESS_RECORD_TYPES}

7374
75+

NAME_GETTER = attrgetter('name')

76+
7477
7578

class QuestionAnswers(NamedTuple):

7679

ucast: _AnswerWithAdditionalsType

@@ -109,13 +112,13 @@ def construct_outgoing_unicast_answers(

109112
110113

def _add_answers_additionals(out: DNSOutgoing, answers: _AnswerWithAdditionalsType) -> None:

111114

# Find additionals and suppress any additionals that are already in answers

112-

sending: Set[DNSRecord] = set(answers.keys())

115+

sending: Set[DNSRecord] = set(answers)

113116

# Answers are sorted to group names together to increase the chance

114117

# that similar names will end up in the same packet and can reduce the

115118

# overall size of the outgoing response via name compression

116-

for answer, additionals in sorted(answers.items(), key=lambda kv: kv[0].name):

119+

for answer in sorted(answers, key=NAME_GETTER):

117120

out.add_answer_at_time(answer, 0)

118-

for additional in additionals:

121+

for additional in answers[answer]:

119122

if additional not in sending:

120123

out.add_additional_answer(additional)

121124

sending.add(additional)