什么时候在我的tal:条件上使用nocall?

时间:2011-04-01 14:29:37

标签: performance plone zope template-tal zpt

我知道,为了提高性能,最好在nocall上使用<tal:condition>以避免调用对象。会欣赏(链接)一些背景,因为这对我来说听起来有点模糊: - )

那你什么时候使用nocall?把它放在我的所有条件下会不会受伤?

谢谢!

4 个答案:

答案 0 :(得分:12)

我倾向于使用tal:condition =“python:variable”代替。这样我就可以总是编写正常的Python表达式,而不必担心默认路径表达式中的魔术行为。

路径表达式将执行许多操作,例如,如果可调用,则调用表达式中的变量。通常你会处理TAL中的工具或内容项,它们都是可调用的。

最常见的错误是使用tal:condition =“content_object”。内容对象可能来自许多API,例如调用任何类型的引用字段都将返回内容对象。目录搜索将返回“大脑”,但在列表中,您经常需要访问这些属性的更多属性,因此您有一个tal:define =“obj brain / getObject”。

调用内容对象会导致呈现对象,就好像浏览器会请求它一样。由于渲染页面通常需要500毫秒到2秒,因此您可以将页面渲染速度降低一段时间。如果你在超过25个项目的循环中执行此操作,我希望页面需要30秒或更长时间才能呈现。

答案 1 :(得分:5)

nocall可让您获得对象属性或方法的“处理程序”。 如果您想知道对象是否具有该属性或方法,您应该使用:

<div tal:condition="nocall:context/method|nothing">
  ...
</div>

|nothing与python代码中的except块类似:如果context/method失败(未定义),则返回nothing。 (这可能不是真正的解释,但可以这样工作)。

使用nocall的另一个原因是获取已知定义的方法处理程序,稍后您将使用:

<div tal:define="method nocall:context/method">
    <span tal:content="python:method(3)" />
    <span tal:content="python:method('hello')" />
    <span tal:content="python:method('whatever')" />
</div>

答案 2 :(得分:1)

我假设您只会将nocall:添加到已经测试过的第一个不可调用项的条件中,并且可能避免使用python内置callable测试可能会给你性能提升。

对这个问题的简短回答是否定的,这对你没有帮助。在我的Macbook Pro笔记本电脑上,每个循环以119ns运行callable(True) 1000次时钟,而普通True语句每循环运行71ns。因此对于简单的python对象,callable测试只需要48ns。另一方面,将nocall:添加到TALES语句中需要额外的处理,几乎肯定会超过刚刚保存的callable测试的48ns开销。

因此,为了提高性能而添加nocall:会适得其反。你最好实现正确的缓存(将plone.app.caching与Varnish结合使用),或者看看Chameleon是否可以用于你的用例。

答案 3 :(得分:0)

不要把它放在所有条件下。它会伤害!特别是那些必须遵循你的代码的人: - )