我有数千个异步任务正在运行。
某些事情大约需要 10 秒才能完成(某些 CPU 密集型工作)。
这使得程序无法工作,因为某些任务需要在其网络连接上回复消息(比如说 5 秒内)。
我当前的想法是以某种方式拦截事件循环。asyncio 模块中必须有某个区域,在每个 epoll()/select() 之间执行事件循环中的所有当前活动任务。如果我可以在每个任务“恢复”之后插入“elapsed = time.time()”和“elapsed = time.time() - elapsed”,我认为这足以找出占用太多时间的任务时间。
我认为相关代码可能在这里,第79行: https: //github.com/python/cpython/blob/master/Lib/asyncio/events.py
def _run(self):
try:
self._context.run(self._callback, *self._args)
except (SystemExit, KeyboardInterrupt):
raise
except BaseException as exc:
cb = format_helpers._format_callback_source(
self._callback, self._args)
msg = f'Exception in callback {cb}'
context = {
'message': msg,
'exception': exc,
'handle': self,
}
if self._source_traceback:
context['source_traceback'] = self._source_traceback
self._loop.call_exception_handler(context)
self = None # Needed to break cycles when an exception occurs.
Run Code Online (Sandbox Code Playgroud)
但我不知道在这里该怎么做才能打印任何有用的信息;我需要一种方法来确定“self._context.run(...)”将执行代码的哪一行。
在过去的 5 个月里,我不眠不休地试图修复我的代码,但还没有成功。
我尝试过使用 CProfiler、line_profile,但它们都没有帮助。它们告诉我执行一个函数所需的时间以及每行花费的时间。我需要找出的是代码在每次循环迭代之间花费了多少时间。 …
如何对异步 Python 脚本(使用 ASYNCIO)进行分析/基准测试?
我通常会做
totalMem = tracemalloc.get_traced_memory()[0]
totalTime = time.time()
retValue = myFunction()
totalTime = time.time() - totalTime
totalMem = tracemalloc.get_traced_memory()[0] - totalMem
Run Code Online (Sandbox Code Playgroud)
这样我就可以节省函数花费的总时间。我学会了如何使用装饰器,我就是这样做的 - 并将所有统计信息转储到文本文件中以供以后分析。
但是,当您拥有 ASYNCIO 脚本时,情况就大不相同了:该函数将在执行“await aiohttpSession.get()”时阻塞,并且控制将返回到事件循环,该循环将运行其他函数。
这样,经过的时间和总分配内存的变化不会显示任何内容,因为我将测量的不仅仅是该函数。
它会起作用的唯一方法是
class MyTracer:
def __init__(self):
self.totalTime = 0
self.totalMem = 0
self.startTime = time.time()
self.startMem = tracemalloc.get_traced_memory()[0]
def stop(self):
self.totalTime += time.time() - self.startTime
self.totalMem += tracemalloc.get_traced_memory()[0] - self.startMem
def start(self):
self.startTime = time.time()
self.startMem = tracemalloc.get_traced_memory()[0]
Run Code Online (Sandbox Code Playgroud)
现在,不知何故,将其插入代码中:
def myFunction():
tracer = MyTracer()
session = aiohttp.ClientSession()
# do …
Run Code Online (Sandbox Code Playgroud) 在C中,或者至少在GCC中,是否有某种方式(使用typedef)是一种与任何其他类型不兼容的类型?
例如,你做:
typedef UINT UID;
typedef UINT AGE;
UID user_id;
AGE user_age;
Run Code Online (Sandbox Code Playgroud)
您可以看到两种类型都是unsigned int(我将其命名为UINT).
您可以计算user_id + user_age.
但是,你想确保UID和AGE永远不会混在一起.
这就是我想要的!
这个想法是为了代码的安全性和正确性,为某些类型指定一些限定符/属性.
然而,混合它们的唯一方法是将两者都转换为UINT,或者将user_age转换为UID.
C语言可能会非常混乱,有时候我们只是因为你使用了错误的值作为参数而只是因为你使用了错误的值作为参数,因为变量具有相似的名称......并且编译器显然永远不会抱怨,因为它们只是为了找出愚蠢的bug.有相同的类型.
我在GCC手册中没有找到任何相关内容,但我会在邮件列表中提出要求.
我只是想知道如何(而且我知道没有,我真正的问题是为什么标准和编译器不提供这个,因为我认为它非常有用并且是相对容易实现的最简单的事情之一在编译器方面)在类型(以及变量)上指定一些ATTRIBUTE,告诉编译器TYPE不应该与任何其他类型混合,除非明确地转换为它.所以真正的问题是: - 为什么这是一个坏主意?(为什么没有编译器考虑它?) - 如果存在这个GCC属性,你还会使用它吗?哦...在我看来我会在这里和那里使用它,只是把这个属性放在几乎所有的typedef然后只是编程; 在第一次编译时会检测到错误的巨大部分 - 以错误的顺序传递参数,在大而复杂的计算中使用错误的变量......
对不起,我的英语不好.