Нашел в тестинге питона пример использования recv_into, recvfrom_into
buf = array.array('c', ' '*1024)
nbytes, addr = self.cli_conn.recvfrom_into(buf)
msg = buf.tostring()[:LENGHT_MSG]
И мой тест(№7) работы с array с заливкой нулями и найденный в интернете тест(№3) на конкатенацию строк показали плохую производительность. Неужели в сочетании с recvfrom_into массив даст лучший результат, да еще с .tostring()? Подозреваю, там тот же самый способ заполнения buff=other.
Плохо то, что параметром эти функции принимают ссылку на array, а не адрес = POINTER(выражение). Следовательно, при каждом вызове массив будет заполняться сначала, а не с указанного адреса. В свою очередь это требует явного копирования массива для сохранения. Или я не прав?
…
Что-то никак не могу придумать какую пользу можно получить от recv_into, recvfrom_into
Вопросы, ответы, размышления:
1) Требуется ли резервирование памяти array.array('c', ‘\x00’*1024) перед вызовом recv_into(buf,1024) ?
2) Очевидно работать с указателями эти функции не умеют, тогда как организовать список таких массивов?
dict[`sock`]=[]
o=dict[`sock`]
o.append(array.array('c','\x00'*1024))
recv_into(o[0],1024)
3) Пусть список o…o создан. Заметим, что у каждого элемента, скорее всего, имеется хвост нулей или пробелов, в зависимости от инициализатора, и каждый элемент это массив. Заметим также, что 0 не является ограничителем, т.к. может являться частью данных. Чтобы выполнить объединение, потребуется определить актуальную длину каждого массива, обрезать хвосты, преобразовать к типу String и выполнить join и наверное в процессе всего этого не раз будет копирование…
4) Пусть мы как-то обошлись одним элементом списка и как-то научились работать с ним через указатель. Тогда мы должны определить максимально возможную длину массива и отвести для каждого открытого сокета максимальный буфер. Пусть максимальная длина сообщения будет 100Kb (небольшой селект из базы данных или что-то подобное). Пусть количество сокетов порядка 100000. Тогда для хранения буферов данных потребуется 10Гб оперативной памяти, большая часть из которой будет составлять “хвосты” из нулей. (В известных мне примерах на C обходятся 8Гб памяти на всё, с большим запасом и обрабатывают 250000 сокетов(в тестовом режиме) за 2-3 секунды.)
Как же работать с этими функциями эффективно?