Найти - Пользователи
Полная версия: Ссылка/псевдоним объекта?
Начало » Python для экспертов » Ссылка/псевдоним объекта?
1 2 3
PyCraft
Согласен, говорит…, но всё равно бесполезно )).
Задача довольно распространенная - работа с сокетами. Должен быть эффективный способ.
Андрей Светлов
А ты у своего StringIO после каждого write getvalue не бери. Не сложно считать длину накопившегося буфера отдельно.
Дальше. Пример непоказательный. Если у тебя обычно пакет за два раза приходит - используй специфический для этого случая алгоритм. Если пакет довольно большой - StringIO ощутимо выигрывает.

И вообще, если переаллокация так сильно бьет по производительности - может стоит от нее совсем отказаться. Использовать внутри chunks, а снаружи можно выглядеть непрерывным куском (впрочем, это сильно зависит от отсобенностей обрабатывающего алгоритма. Если потоковый - вообще может все отлично лечь).

Далее. Если говорить о сокетах - использовать socket.recv_into никто не пытался?

Кажется, задачу решают не с того конца….
bialix
Андрей Светлов
Кажется, задачу решают не с того конца….
Как обычно…
PyCraft
Андрей Светлов
chunks, socket.recv_into
Буду копать в этом направлении. Кстати, что можно по этому поводу почитать?
Ferroman
Google
PyCraft
Ferroman
Google
К сожалению, полноценной информации по этим функциям найти не удалось. Много ссылок, но мало примеров и описаний.
PyCraft
Вот нашел похожий тест по способам быстрой конкатенации строк.
http://www.skymind.com/~ocrow/python_string/
PyCraft
Нашел в тестинге питона пример использования 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 секунды.)

Как же работать с этими функциями эффективно?
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB