调试慢程序;从mid重新启动

2024-10-05 22:02:16 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个程序计算速度慢,我想调试算法。现在总是重新运行所有的东西是非常乏味的,我宁愿从程序中间重新启动。你能想出一些聪明的方法来达到这个目的吗?在

第一个模糊的想法是定义检查点(在这里我进行函数调用),在这里我用pickle和/或sqlite(sqlite能够检查中间数据)保存局部变量和大数据。稍后我可以尝试调用程序,告诉它在特定的检查点重新启动。不过,我不想为了这个目的在检查点之间分割所有代码块。在

有人知道如何解决这个调试问题吗?在


Tags: 数据方法代码程序目的算法sqlite定义
3条回答

使你的程序更模块化。理想情况下,主代码块应该类似于

import config
import my_numerics
import post_processing

my_numerics.configure(config.numerics)
values = my_numerics.run()

post_processing.run(values, config.post_processing)

你明白了。然后很容易生成一个“mock”numerics对象,该对象返回预先计算的数据,并将其传递给后处理。在


编辑:我还是不明白。以下是您的问题的正确伪代码吗?在

^{pr2}$

也就是说,你想在数字运行的中途中断(不是在末尾),比如在第三个循环的开始,而不必重新运行前两个?在

如果是这样,即使循环不包含太多代码,也应模块化设计:

input_data = np.load(some_stuff)
stage_one = do_thing_one(input_data)
stage_two = do_thing_two(stage_one)
stage_three = do_thing_three(stage_two)

第一种方法是通过隐式接口(即局部变量字典)在不同的阶段之间传输数据。这是不好的,因为您还没有定义要使用哪些变量,因此您不能为了测试/调试目的而模拟它们。第二种方法定义函数之间的(基本)接口。现在您不再关心do_thing_one做什么了,只要它接受一些输入数据并返回一些输出数据。{cd2>这意味着你可以调试

stage_two = np.load(intermediate_stuff)
stage_three = do_thing_three(stage_two)

只要stage_two中的数据格式正确,它来自何处都无关紧要。在

一个google搜索让我找到了CryoPID,如果你是在基于linux的系统上开发的话,这可能就可以了。它声称能够挂起一个进程并将其保存到一个文件中,然后再重新启动它,即使是在另一台计算机上。不过我还没有测试过。在

单元测试

这就是为什么存在单元测试。尝试使用小的“示例数据”pyunit,或者使用非常简单的函数doctest。在

小型测试程序

如果出于某种原因你真的需要交互性,我通常编写一个交互式的小程序,作为一个有效的单元测试。在

def _interactiveTest():
    ...
    import code
    code.interact(local=locals())

if __name__=='__main__':
    _interactiveTest()

如果只测试某个特定的部分,通常可以忽略加载主程序的大块;根据需要调整体系结构,以避免初始化程序中不需要的部分。这就是为什么人们会说“让你的程序更模块化”,这就是模块化的意思:程序的小部分独立,让你重用它们或者(在这种情况下)单独加载它们。在

在程序中调用解释器

您还可以在程序中的任何时候,下拉到一个解释器中,并传入局部变量(如上所示)。这有点像“穷人的调试器”,但我觉得它足够有效。=)

单片算法

去过那里,做了。有时候,你的工作流程无法进一步模块化,事情开始变得难以处理。在

你建立检查点的直觉是非常好的,我也使用这个直觉:如果你在一个解释器环境中工作,或者嵌入一个解释器,你就不必像重新运行脚本那样频繁地处理这个问题。序列化数据可以工作,但它会带来从磁盘读写的大量开销;您希望数据集保留在内存中。然后您可以做类似test1 = algorithm(data), test2 = algorithm(data)(这假设您的算法不是一个就地算法;如果是,请在每次测试之前使用“写入时复制”或复制数据结构)。在

如果您在尝试了以上所有方法后仍有问题,那么您可能是:

  • 使用真实的数据集;你应该只是一个较小的测试数据集来进行原型设计!在
  • 使用效率低下的算法。在

作为最后的手段,您可以对代码进行概要分析以找出瓶颈。在

其他

可能有强大的python调试器。我想日蚀有一个。在

另外,我个人会避免使用reload <modulename>,我发现这会让人头疼,而不是解决问题。在

相关问题 更多 >