English 中文(简体)
Python 中的快速插接插接器
原标题:Faster sockets in Python

我有一个客户端用 Python 写成服务器, 它通过局域网运行 。 算法中的一部分使用套接字快速读取, 其执行速度比 < a href=" http:// pastie. org/ 3962231, rel 几乎是 C++ 中写到的 " noreferrer" 。 使 Python 套接字读得更快有什么解决办法?

我有一些简单的缓冲装置, 和我的班级 工作插座是这样的:

import socket
import struct

class Sock():
    def __init__(self):
        self.s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.recv_buf = b  
        self.send_buf = b  

    def connect(self):
        self.s.connect(( 127.0.0.1 , 6666))

    def close(self):
        self.s.close()

    def recv(self, lngth):
        while len(self.recv_buf) < lngth:
                self.recv_buf += self.s.recv(lngth - len(self.recv_buf))

        res = self.recv_buf[-lngth:]
        self.recv_buf = self.recv_buf[:-lngth]
        return res

    def next_int(self):
        return struct.unpack("i", self.recv(4))[0]

    def next_float(self):
        return struct.unpack("f", self.recv(4))[0]

    def write_int(self, i):
        self.send_buf += struct.pack( i , i)

    def write_float(self, f):
        self.send_buf += struct.pack( f , f)

    def flush(self):
        self.s.sendall(self.send_buf)
        self.send_buf = b  

P.S.:概况分析还表明,大部分时间用于阅读插座。

<强度> 编辑: 因为数据是用已知大小的区块接收的, 我可以立刻读取整个区块。 所以我把我的代码改成了这个 :

class Sock():
    def __init__(self):
        self.s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.send_buf = b  

    def connect(self):
        self.s.connect(( 127.0.0.1 , 6666))

    def close(self):
        self.s.close()

    def recv_prepare(self, cnt):
        self.recv_buf = bytearray()
        while len(self.recv_buf) < cnt:
            self.recv_buf.extend(self.s.recv(cnt - len(self.recv_buf)))

        self.recv_buf_i = 0

    def skip_read(self, cnt):
        self.recv_buf_i += cnt

    def next_int(self):
        self.recv_buf_i += 4
        return struct.unpack("i", self.recv_buf[self.recv_buf_i - 4:self.recv_buf_i])[0]

    def next_float(self):
        self.recv_buf_i += 4
        return struct.unpack("f", self.recv_buf[self.recv_buf_i - 4:self.recv_buf_i])[0]

    def write_int(self, i):
        self.send_buf += struct.pack( i , i)

    def write_float(self, f):
        self.send_buf += struct.pack( f , f)

    def flush(self):
        self.s.sendall(self.send_buf)
        self.send_buf = b  

recv 来源于 socket 的 < exter_int 似乎是最佳的。 但是现在 next_int and next_float 成为第二个瓶颈,他们每次打开解锁的电话大约需要1 msec (3,000 CPU 周期) 。 是否有可能更快一些, 如 C++ 中的 C++?

最佳回答

您最近的瓶颈在 next_int next_float 中,因为您从 byeararray 创建中间字符串,而且您每次只解开一个值。

struct 模块有一个 unpack_ from unpack_ from 模块,该模块取用缓冲和偏移。 这样做更有效率, 因为不需要从您的 bytearray 创建中间字符串 :

def next_int(self):
    self.recv_buf_i += 4
    return struct.unpack_from("i", self.recv_buf, self.recv_buf_i-4)[0]

此外, struct 模块可以一次解开多个值。 目前, 您会为每个值从 Python 到 C (通过模块) 调用 。 您最好将其调用为更少的时间, 并让它对每次调用做更多的工作 :

def next_chunk(self, fmt): # fmt can be a group such as "iifff" 
    sz = struct.calcsize(fmt) 
    self.recv_buf_i += sz
    return struct.unpack_from(fmt, self.recv_buf, self.recv_buf_i-sz)

如果您知道 fmt 将始终是 4 位元整数和浮点, 您可以用 > 4 * len(fmt) 替换 struct. calcision(fmt)

最后,作为一个优先事项,我认为这段文字更清楚明了:

def next_chunk(self, fmt): 
    sz = struct.calcsize(fmt) 
    chunk = struct.unpack_from(fmt, self.recv_buf, self.recv_buf_i)
    self.recv_buf_i += sz
    return chunk
问题回答

暂无回答




相关问题
Can Django models use MySQL functions?

Is there a way to force Django models to pass a field to a MySQL function every time the model data is read or loaded? To clarify what I mean in SQL, I want the Django model to produce something like ...

An enterprise scheduler for python (like quartz)

I am looking for an enterprise tasks scheduler for python, like quartz is for Java. Requirements: Persistent: if the process restarts or the machine restarts, then all the jobs must stay there and ...

How to remove unique, then duplicate dictionaries in a list?

Given the following list that contains some duplicate and some unique dictionaries, what is the best method to remove unique dictionaries first, then reduce the duplicate dictionaries to single ...

What is suggested seed value to use with random.seed()?

Simple enough question: I m using python random module to generate random integers. I want to know what is the suggested value to use with the random.seed() function? Currently I am letting this ...

How can I make the PyDev editor selectively ignore errors?

I m using PyDev under Eclipse to write some Jython code. I ve got numerous instances where I need to do something like this: import com.work.project.component.client.Interface.ISubInterface as ...

How do I profile `paster serve` s startup time?

Python s paster serve app.ini is taking longer than I would like to be ready for the first request. I know how to profile requests with middleware, but how do I profile the initialization time? I ...

Pragmatically adding give-aways/freebies to an online store

Our business currently has an online store and recently we ve been offering free specials to our customers. Right now, we simply display the special and give the buyer a notice stating we will add the ...

Converting Dictionary to List? [duplicate]

I m trying to convert a Python dictionary into a Python list, in order to perform some calculations. #My dictionary dict = {} dict[ Capital ]="London" dict[ Food ]="Fish&Chips" dict[ 2012 ]="...