- mongodb - 在 MongoDB mapreduce 中,如何展平值对象?
- javascript - 对象传播与 Object.assign
- html - 输入类型 ="submit"Vs 按钮标签它们可以互换吗?
- sql - 使用 MongoDB 而不是 MS SQL Server 的优缺点
我正在做一个从 udp 套接字接收样本的音频播放器,一切正常。但是当我实现了一个 Lost Concealment 算法时,播放器未能以异常(exception)的速率保持沉默(每 10 毫秒发送一个包含多个 160 字节的列表)。
当使用 pyaudio 播放音频时,使用阻塞调用 write 播放一些样本,我注意到它在样本持续时间内平均阻塞。所以我创建了一个新的专用流程来播放样本。
主进程处理音频的输出流,并使用 multiprocessing.Pipe 将结果发送到该进程。我决定使用 multiprocessing.Pipe 因为它应该比其他方式更快。
不幸的是,当我在虚拟机上运行程序时,比特率是我在快速 PC 上获得的一半,这并没有达到目标比特率。
经过一些测试,我得出结论,导致延迟的原因是 Pipe 的函数 send
。
我做了一个简单的基准测试脚本(见下文)来查看传输到进程的各种方法之间的差异。该脚本不断发送 [b'\x00'*160]
5 秒钟,并计算总共发送了多少字节字节对象。我测试了以下发送方法:“不发送”、multiprocessing.Pipe、multiprocessing.Queue、multiprocessing.Manager、multiprocessing.Listener/Client,最后是socket.socket:
我的“快速”PC 运行窗口 7 x64 的结果:
test_empty : 1516076640
test_pipe : 58155840
test_queue : 233946880
test_manager : 2853440
test_socket : 55696160
test_named_pipe: 58363040
VirtualBox 的 VM guest 运行 Windows 7 x64 的结果,主机运行 Windows 7 x64:
test_empty : 1462706080
test_pipe : 32444160
test_queue : 204845600
test_manager : 882560
test_socket : 20549280
test_named_pipe: 35387840
from multiprocessing import Process, Pipe, Queue, Manager
from multiprocessing.connection import Client, Listener
import time
FS = "{:<15}:{:>15}"
def test_empty():
s = time.time()
sent = 0
while True:
data = b'\x00'*160
lst = [data]
sent += len(data)
if time.time()-s >= 5:
break
print(FS.format("test_empty", sent))
def pipe_void(pipe_in):
while True:
msg = pipe_in.recv()
if msg == []:
break
def test_pipe():
pipe_out, pipe_in = Pipe()
p = Process(target=pipe_void, args=(pipe_in,))
p.start()
s = time.time()
sent = 0
while True:
data = b'\x00'*160
lst = [data]
pipe_out.send(lst)
sent += len(data)
if time.time()-s >= 5:
break
pipe_out.send([])
p.join()
print(FS.format("test_pipe", sent))
def queue_void(q):
while True:
msg = q.get()
if msg == []:
break
def test_queue():
q = Queue()
p = Process(target=queue_void, args=(q,))
p.start()
s = time.time()
sent = 0
while True:
data = b'\x00'*160
lst = [data]
q.put(lst)
sent += len(data)
if time.time()-s >= 5:
break
q.put([])
p.join()
print(FS.format("test_queue", sent))
def manager_void(l, lock):
msg = None
while True:
with lock:
if len(l) > 0:
msg = l.pop(0)
if msg == []:
break
def test_manager():
with Manager() as manager:
l = manager.list()
lock = manager.Lock()
p = Process(target=manager_void, args=(l, lock))
p.start()
s = time.time()
sent = 0
while True:
data = b'\x00'*160
lst = [data]
with lock:
l.append(lst)
sent += len(data)
if time.time()-s >= 5:
break
with lock:
l.append([])
p.join()
print(FS.format("test_manager", sent))
def socket_void():
addr = ('127.0.0.1', 20000)
conn = Client(addr)
while True:
msg = conn.recv()
if msg == []:
break
def test_socket():
addr = ('127.0.0.1', 20000)
listener = Listener(addr, "AF_INET")
p = Process(target=socket_void)
p.start()
conn = listener.accept()
s = time.time()
sent = 0
while True:
data = b'\x00'*160
lst = [data]
conn.send(lst)
sent += len(data)
if time.time()-s >= 5:
break
conn.send([])
p.join()
print(FS.format("test_socket", sent))
def named_pipe_void():
addr = '\\\\.\\pipe\\Test'
conn = Client(addr)
while True:
msg = conn.recv()
if msg == []:
break
def test_named_pipe():
addr = '\\\\.\\pipe\\Test'
listener = Listener(addr, "AF_PIPE")
p = Process(target=named_pipe_void)
p.start()
conn = listener.accept()
s = time.time()
sent = 0
while True:
data = b'\x00'*160
lst = [data]
conn.send(lst)
sent += len(data)
if time.time()-s >= 5:
break
conn.send([])
p.join()
print(FS.format("test_named_pipe", sent))
if __name__ == "__main__":
test_empty()
test_pipe()
test_queue()
test_manager()
test_socket()
test_named_pipe()
在我的程序中,在尝试使用队列而不是管道之后。 我得到了巨大的提升。
在我的计算机上,使用 Pipes 我得到 +- 16000 B/s,使用 Queues 我得到 +-750 万 B/s。在虚拟机上,我的速度从 +-13000 B/s 提高到 650 万 B/s。使用 Queue instread 的 Pipe 字节数增加了大约 500 倍。
当然我不会每秒播放数百万字节,我只会播放正常的声音速率。 (在我的情况下是 16000 B/s,与上面的值一致)。
但关键是,我可以将速率限制在我想要的范围内,同时仍有时间完成其他计算(如从套接字接收、应用声音算法等)
最佳答案
我不能肯定地说,但我认为您要处理的问题是同步 I/O 与异步 I/O。我的猜测是 Pipe 以某种方式以同步方式结束,而 Queue 以异步方式结束。为什么一个是默认一种方式而另一种是另一种方式可能会更好地通过这个问题和答案来回答:
关于Python 3.4 多处理队列比 Pipe 快,出乎意料,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26908909/
这看起来很基础,但我想不通。是否有一种简单的 CSS 唯一方法可以使 cssa 真正快速淡入并缓慢淡出。这是为了改变多个 div 的颜色。大约 0.5 秒的缓入和 2 秒的缓出。 谢谢! 最佳答案 你
我一直在用各种语言和实现实现相同的代码(在 Blackjack 中发牌而不爆牌的方法的数量)。我注意到的一个奇怪之处是,Python 在 C 中调用分区函数的实现实际上比用 C 编写的整个程序快一点。
如果我没看错,/ 意味着它右边的节点必须是左边节点的直接子节点,例如/ul/li 返回 li 项,它们是作为文档根的 ul 项的直接子项。 //ul//li 返回 li 项,它们是文档中某处任何 ul
如何随机更新一个表。所以你给一列一个随机值。并且该列(例如“顶部”)是唯一的。如果您在数字 10 到 20 之间进行选择,并且您有 10 行,那么您就不能有未使用的数字。如果你有 Test table
这在一小部分是一个问题(因为我不明白为什么它会有所不同),在很大程度上是一篇希望能帮助其他一些可怜的程序员的帖子。 我有一个代码库,是我大约 5-7 年前第一次开始 Android 编程时编写的,它具
我正在尝试过滤关系表以获得满足两个条件的表子集(即:我想要 color_ids 为 1 或 2 的条目的所有 ID)。这是一张结实的 table ,所以我正在尝试尽可能多地进行优化。 我想知道是否有人
在上一篇《聊聊PHP中require_once()函数为什么不好用》中给大家介绍了PHP中require_once()为什么不好用的原因,感兴趣的朋友可以去阅读了解一下~ 那么本文将给大家介绍PH
很难说出这里问的是什么。这个问题模棱两可、含糊不清、不完整、过于宽泛或言辞激烈,无法以目前的形式合理回答。如需帮助澄清此问题以便可以重新打开,visit the help center . 10年前关
有没有办法提高glReadPixels的速度?目前我做: Gdx.gl.glReadPixels(0, 0, Gdx.graphics.getWidth(), Gdx.graphics.getHeig
通常,我以函数形式`:=`()来计算data.table中的多列,认为这是最有效的方法。但是我最近发现它比简单地重复使用:=慢。至少在我的电脑上。 我猜想:=的功能形式可能会产生一些开销,但这是它变慢
我的问题是针对 Windows 环境中多线程的性能问题。 在测试我的代码后,我得到的结果是增加线程数不会提高并行计算的性能,并且在经过一些计数后变得更少。到底是怎么回事?是否可以找出最佳线程数的公式:
我看到很少有相同问题的主题,但我仍然无法解决我的问题。这是我的代码 - 使用 XOR 加密的 C 套接字编程 当服务器和客户端连接时:- 用户发送消息,例如:你好- 服务器响应,例如:(服务器):你好
我正在定义继承自 Shape 类并实现“几何”属性的形状。 这是一个例子: public class Landmark : Shape { public override bool IsInB
相同代码在 Android(1Ghz Snapdragon)上的执行速度比我在 3.3 Ghz Core 2 Duo 的 PC(在桌面应用程序中)快 2 倍(PC 的类被复制到 Android 项目)
我需要将一个值与一组数组进行比较。但是,我需要比较 foreach 中的多个值。如果使用 in_array,它可能会很慢,真的很慢。有没有更快的选择?我当前的代码是 foreach($a as $b)
这个问题在这里已经有了答案: How do I write a correct micro-benchmark in Java? (11 个答案) 关闭 9 年前。 今天我做了一个简单的测试来比较
如果比较不应该以这种方式进行,我深表歉意。我是编程新手,只是很好奇为什么会这样。 我有一个包含词嵌入的大型二进制文件 (4.5gb)。每行都有一个单词,后面跟着它的嵌入,它由 300 个浮点值组成。我
我经历了几个不同的四元数乘法实现,但我很惊讶地发现引用实现是迄今为止我最快的实现。这是有问题的实现: inline static quat multiply(const quat& lhs, cons
我写了一个简单的例子,估计调用虚函数的平均时间,使用基类接口(interface)和dynamic_cast和调用非虚函数。这是它: #include #include #include #in
有没有人知道比“StackWalk”更好/更快的获取调用堆栈的方法?我还认为 stackwalk 在有很多变量的方法上也会变慢......(我想知道商业分析员是做什么的?)我在 Windows 上使用
我是一名优秀的程序员,十分优秀!