5

Psyco是 Python 的专门编译器。该文件指出

Psyco 可以并且将使用大量内存。

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

编辑:感谢到目前为止的答案。有三个可能的竞争者。

  • 编写多个专用块,每个块都需要内存
  • 由于动态编译源而产生的开销
  • 由于捕获足够的数据来进行动态分析而产生的开销

问题是,哪一个是内存使用的主导因素?我有自己的看法。但是我要增加赏金,因为我想接受实际上正确的答案!如果有人可以证明或证明大部分内存的使用位置,我会接受。否则,无论社区投票给谁,都将在赏金结束时自动接受。

4

4 回答 4

10

来自 psyco 网站“与 JIT 编译器的传统方法的不同之处在于,Psyco 编写了相同块的多个版本(一个块有点像一个函数),通过专门针对某些类型的变量(一种“种类”可以表示一种类型,但它更通用)”

于 2009-09-17T11:31:48.467 回答
5

“Psyco 使用您的程序操作的实际运行时数据来编写可能的多个机器代码版本,每个版本都针对不同类型的数据进行了不同的专门化。” http://psyco.sourceforge.net/introduction.html

许多 JIT 编译器使用静态类型语言,因此它们知道类型是什么,因此可以仅为已知类型创建机器代码。如果类型是多态的并优化更常见的路径,则更好的会进行动态分析;这也通常在具有动态类型的语言中完成†。Psyco 似乎在对冲它的赌注,以避免进行完整的程序分析来确定可能是什么类型,或者通过分析来找出正在使用的类型是什么。

† 我从来没有深入到 Python 来确定它是否具有动态类型(在使用该类型创建对象后可以在运行时更改其结构的类型),或者只是常见的实现在运行时检查类型;大多数文章只是对动态类型赞不绝口,而没有在 Python 的上下文中实际定义它。

于 2009-09-17T12:03:45.893 回答
2

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

所以我认为大内存需求是由于它将源加载到内存中,然后在运行时编译它。您尝试和编译的源代码越多,它需要的资源就越多。我猜想,如果它试图在此基础上对其进行优化,它会考虑多种可能的解决方案来尝试确定最佳情况。

于 2009-09-17T11:25:24.317 回答
2

绝对 psyco 内存使用来自已编译的汇编程序块。Psyco 有时会受到功能过度专业化的困扰,这意味着有多个版本的汇编程序块。此外,这也很重要,即使与它关联的代码已死,psyco 也永远不会释放分配的汇编程序块。

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

于 2009-10-23T06:17:47.590 回答