Python 中更快的套接字

2024-01-17

我有一个用 Python 编写的服务器客户端,它通过 LAN 运行。该算法的某些部分使用套接字密集读取,其执行速度比几乎一样的 http://pastie.org/3962231用 C++ 编写。有哪些解决方案可以使 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.:分析还表明大部分时间都花在读取套接字上。

Edit:由于数据是以已知大小的块形式接收的,因此我可以立即读取整个块。所以我将我的代码更改为:

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'ing from socket 在此代码中看起来是最佳的。但现在next_int and next_float成为第二个瓶颈,每次调用大约需要 1 毫秒(3000 个 CPU 周期)来解包。是否有可能让它们更快,就像在 C++ 中一样?


您最近的瓶颈在于next_int and next_float因为您从创建中间字符串bytearray因为您一次只能解压一个值。

The struct模块有一个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 字节整数和可以替换的浮点数struct.calcsize(fmt) with 4 * len(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
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Python 中更快的套接字 的相关文章

随机推荐

  • Selenium - 跨域和 HTTPS 问题

    我使用 Selenium 来测试我的网站 该网站需要访问外部目录才能从中选择一些项目 问题是该目录是通过 HTTPS 协议发布在另一个域上的 我在互联网上搜索并阅读了许多有关 Selenium 和跨域问题的主题 但我仍然没有找到答案 有些主
  • 在 python seaborn 图中创建多列图例

    我在用seaborn distplot python3 并希望每个系列有 2 个标签 我尝试了一种黑客字符串格式方法 如下所示 bigkey and bigcount are longest string lengths of my key
  • 使用单个标识符 REST 方式嵌套资源路由

    在我的 Rails 应用程序中 两个实体之间有一个相当标准的 has many 关系 AFoo有零个或多个Bars a Bar恰好属于一个Foo Foo 和 Bar 均由单个整数 ID 值标识 这些值在其各自的所有实例中都是唯一的 Bar
  • iOS 保持状态栏为纵向

    我有一个使用接近传感器的应用程序 但接近传感器在横向模式下不起作用 我听说如果你将状态栏保持在纵向模式 传感器就会工作 我已经尝试过 但没有成功 UIApplication sharedApplication setStatusBarOri
  • SSRS 在组内交替行颜色

    我在获取替代行颜色时遇到一些问题 我尝试了不同的表达方式 这是我已经完成的最接近的表达方式 IIF RunningValue Fields agent name Value CountDistinct Nothing MOD 2 1 Gai
  • CHM 格式替代品?

    Microsoft CHM 格式非常有用 因为它提供了以下功能 带有树视图的目录 指数 索引搜索 基于 HTML 源 但这种格式已经过时并且有很多缺点 存在安全问题 允许执行 JavaScript 代码 不知道新的 HTML 格式 没有记录
  • 反应过渡组出现过渡无法正常工作

    我在用着反应过渡基团 http reactcommunity org react transition group transition渲染组件时处理动画 CSSTransition 我想要一个组件的简单淡入 转出似乎工作正常 但转入则不然
  • Tkinter 单选按钮指示器无法识别

    我希望我的单选按钮通过设置 Indicatoron 0 来使用本页提到的按钮框界面 http effbot org tkinterbook radiobutton htm http effbot org tkinterbook radiob
  • 使用多线程时如何使用Delphi设计时FireDac TFDQuery?

    我想设计我的TFDQuery使用组件编辑器 即在设计时设置 SQL 字符串 选项等 然后在线程中使用查询 我的问题是 线程的每个运行实例都需要自己的查询实例 否则它将不是线程安全的 我是否应该在线程开始运行时克隆查询 即在线程的 Execu
  • 检查 Windows 更新是否可用

    是否可以通过编程方式检查 Windows 是否有可用的新更新 欢迎任何建议 谢谢 The Windows更新代理 http msdn microsoft com en us library aa387287 28VS 85 29 aspxA
  • 如何将当前文档的innerHTML下载为文件?

    有没有办法可以下载当前文档innerHTML作为文件以编程方式 我做了以下尝试但没有成功 它确实下载了当前文档的源代码 但这不是我想要的 因为我想保留任何加载后的文档修改 var save document createElement a
  • 如何使用gin作为服务器编写prometheus导出器指标

    这是官方的prometheus golang client示例 package main import log net http github com prometheus client golang prometheus github c
  • 具有资源文件的动态本地化 WPF 应用程序

    试图使我的 wpf 应用程序本地化 我遵循这个 CodeProject 教程 https www codeproject com Articles 299436 WPF Localization for Dummies 我创建了本地化资源文
  • 二维对象数组返回类型 - NSubstitute

    我遇到强制转换异常 System InvalidCastException 无法将类型 System Object 的对象强制转换为类型 System Object 在 Castle Proxies ITestProxy Get2DArra
  • TortoiseGit 中的“远程跟踪分支”在哪里?

    如何在TortoiseGit中找到 远程跟踪分支 以设置从中拉取的默认分支 打开 浏览参考 对话框 参见https tortoisegit org docs tortoisegit tgit dug browse ref html http
  • R:内部函数可以使用外部函数的变量吗?

    内部函数可以使用调用它的函数环境中存在的变量吗 inner lt function x return x y z a outer lt function x y z a lt x y z inner x 在这里 当我打电话时inner x
  • 使用 sympy 计算多元函数的泰勒级数

    我正在尝试使用 SymPy 计算依赖于三角函数的函数的泰勒级数sinc here http docs sympy org dev modules mpmath functions trigonometric html sinc functi
  • @ActiveProfiles 值未分配给配置

    如果我将它们设置为虚拟机参数 我的活动配置文件将正常工作 我有一个想要使用的测试 ActiveProfiles local 这是我正在使用的类注释 RunWith SpringJUnit4ClassRunner class ContextC
  • 使用 Twitter Bootstrap,如何自定义一页的 h1 文本颜色,而将其他页面保留为默认颜色?

    在我的索引页面上 我希望 h1 文本颜色为白色并带有阴影 但我不想更改其他页面上 h1 的默认行为 我怎样才能实现这个目标 在 Bootstrap 3 中 以下是更改文本颜色的类 p class text muted p grey p cl
  • Python 中更快的套接字

    我有一个用 Python 编写的服务器客户端 它通过 LAN 运行 该算法的某些部分使用套接字密集读取 其执行速度比几乎一样的 http pastie org 3962231用 C 编写 有哪些解决方案可以使 Python 套接字读取速度更