Python 为什么Psyco使用大量内存?

Python 为什么Psyco使用大量内存?,python,memory,compiler-construction,jit,psyco,Python,Memory,Compiler Construction,Jit,Psyco,是Python的专业编译器。 Psyco可以而且将使用大量内存 这种内存使用的主要原因是什么?大量的内存开销通常是JIT编译器的一个特性吗 编辑:感谢您迄今为止的回答。有三个可能的竞争者 写入多个专用块,每个块都需要内存 动态编译源代码导致的开销 由于捕获足够的数据以进行动态分析而导致的开销 问题是,哪一个是记忆使用的主导因素?我有自己的看法。但我要加上一笔赏金,因为我想接受事实上正确的答案!如果有人能证明大部分内存是在哪里使用的,我会接受的。否则社区投票支持的人将在悬赏结束时自动被接受 P

是Python的专业编译器。

Psyco可以而且将使用大量内存

这种内存使用的主要原因是什么?大量的内存开销通常是JIT编译器的一个特性吗

编辑:感谢您迄今为止的回答。有三个可能的竞争者

  • 写入多个专用块,每个块都需要内存
  • 动态编译源代码导致的开销
  • 由于捕获足够的数据以进行动态分析而导致的开销
问题是,哪一个是记忆使用的主导因素?我有自己的看法。但我要加上一笔赏金,因为我想接受事实上正确的答案!如果有人能证明大部分内存是在哪里使用的,我会接受的。否则社区投票支持的人将在悬赏结束时自动被接受

Psyco的内存开销目前很大。随着时间的推移,我的工作量有所减少,但这仍然是一项开销此开销与Psyco重写的Python代码量成正比;因此,如果您的应用程序有一些算法“核心”函数,那么这些是您希望Psyco加速的函数,而不是整个程序

所以我认为需要大量内存是因为它将源代码加载到内存中,然后在运行时编译它。您尝试和编译的源代码越多,它需要的就越多。我猜,如果它试图将其视为最重要的因素,它会考虑多种可能的解决方案,试图找出最佳情况

来自psyco网站“与传统的JIT编译器方法不同的是,psyco编写相同块的多个版本(一个块是一个函数),通过专门化某些类型的变量(一个“种类”可能意味着一种类型,但它更通用),对其进行优化。”

Psyco使用您的程序操纵的实际运行时数据来编写可能的多个版本的机器代码,每个版本针对不同类型的数据进行不同的专门化

许多JIT编译器使用静态类型语言,因此它们知道类型是什么,因此可以仅为已知类型创建机器代码。如果类型是多态的,并且优化了更常见的路径,那么更好的方法会进行动态分析;这通常也适用于具有动态类型†的语言。Psyco似乎在避险,以避免进行完整的程序分析以确定可能的类型,或分析以找到正在使用的类型


†我从来没有深入研究过Python,以确定它是否有动态类型(使用该类型创建对象后,其结构可以在运行时更改的类型),或者只是常见的实现仅在运行时检查类型;大多数文章只是对动态类型大肆渲染,而没有在Python上下文中真正定义它。

显然,psyco内存使用来自编译的汇编程序块。Psyco有时会遭受函数过度专业化的困扰,这意味着汇编程序有多个版本 阻碍。同样,这也是非常重要的,psyco从不释放一次分配的汇编程序块 即使与之相关的代码已经失效


如果您在linux下运行您的程序,您可以查看/proc/xxx/smap以看到匿名内存块的增长,它位于与堆不同的区域。这是写汇编程序的匿名mmap部分,在没有psyco的情况下运行时,汇编程序当然会消失。

很好地使用&dagger来实现一个看起来合适的脚注!您完全可以动态地将成员和函数添加到类的实例化中。您可以卸载、修改然后重新加载包含类的模块,并开始usnig新的模块。这会更改该类的现有对象,还是仅更改重新加载后创建的新对象?如果更改该类,则创建的对象将与原始类保持存在。您可以直接修改对象,使其与原始类不同。