ColdFusion:比isDefined()更高效的structKeyExists()函数

22

在ColdFusion中,以下哪个更高效?

isDefined('url.myvar')
或者
structKeyExists(url, 'myvar')
2个回答

42

现在的 ColdFusion 版本(CF8+)中,两者之间的速度差距并不是很大。然而,structKeyExists确实略快一些。原因如下。

使用 isDefined 时,传入的字符串会在多个作用域中查找作为键名。从 CF9 开始,按照以下顺序检查作用域列表: (来源)

  1. 本地作用域(仅限函数本地作用域、UDFs和CFCs)
  2. 参数
  3. 线程本地作用域(仅在线程内部)
  4. 查询(不是真正的作用域,在查询循环内部应用于变量)
  5. 线程
  6. 变量
  7. CGI
  8. CFFile
  9. URL
  10. Form
  11. Cookie
  12. 客户端

即使您在 isDefined 中使用了作用域名称(例如:if isDefined('variables.foo')),列表仍将按顺序进行检查;如果定义了变量 local.variables.foo,它将在 variables.foo 之前被找到。

另一方面,structKeyExists 仅在传递给它的结构中搜索键名的存在;因此,需要查找的位置要少得多。

通过使用更明确的代码(如 structKeyExists),不仅可以获得一些性能优势,而且代码在我看来更易读和可维护。


非常好!看到它如何以不同的方式处理函数真是有趣。 - James T
我也认为 ColdFusion 需要在提供的字符串上运行 eval。StructKeyExists 可以避免很多工作。 - Aaron Greenlee
2
structKeyExists() 存在一个大问题。如果您使用 ColdFusion 反序列化 JSON 字符串,并且您有一个值为 null 的属性 myVal,那么 structKeyExists(object, "myVal") 将返回 true,而 isDefined("object.myVal") 不会。换句话说,如果您在使用 structKeyExists() 检查后尝试访问属性 object.myVal,则会出现错误。 - android
返回翻译文本:是的,但这是CF处理空值的错误。每当null是可接受的值时,在structKeyExists()调用之前尝试使用isNull()。 - Adam Tuttle

13

使用易于阅读且最能展示你正在做的内容的那个。

两者之间的差异非常小,很可能根本不值得担心。

除非有经过证明的且可重复测试的案例证明代码缓慢,否则不要浪费时间优化代码。


2
+1. 理解这两个函数的操作方式肯定是值得的。但是除非你遇到了性能问题,我认为编写可读性强且正确行为的代码更加重要。 - Leigh
我完全同意,但我仍然是structKeyExists的普通用户。我发现它的显式性质使一切都清晰明了,而isDefined并不总是如此,这会导致在几个月或几年后回到旧代码(和/或别人的代码)时需要更多的时间和头痛。 - Adam Tuttle
虽然IsDefined()的命名更直观,但你刚才描述的仍然是选择一个而不是另一个更好的理由,比起过早担心性能问题。至少在我看来;-) - Leigh 8分钟前 - Leigh
非常晚的评论,但我建议有时页面会由于此关键问题超时,抛出网关错误。 - Regual

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接