使用@Function时SSJS是否有性能损失?

Dav*_*edy 4 xpages

如果我想在SSJS中解析文本字段,则有两个主要工具.内置的JavaScript代码和新转换的@Functions.@Functions比使用纯javascript慢吗?或者没有真正的区别?

viewScope.put("length", tmpStr.length)
Run Code Online (Sandbox Code Playgroud)

viewScope.put("length:, @Length(tmpStr))
Run Code Online (Sandbox Code Playgroud)

Tim*_*ony 16

在运行时,所有SSJS都被解析为AST(抽象语法树).换句话说,你的代码只是保持一个字符串,直到它执行的确切时刻,此时解析器检查该字符串以语法识别代码包含的内容:哪些字符表示变量,即运算符,函数等.解析完成后,运行时引擎能够运行Java代码,这是JavaScript代码设计的粗略近似.

这就是为什么SSJS 总是比直接等效的Java慢的原因:如果你刚开始用Java编写代码,那么在你构建项目时它就被编译成字节码,但也许更重要的是,在运行时它不需要"猜测"通过解析字符串来运行的代码...它只运行您已定义的Java代码.

另一方面,这个过程没有什么能够将各种@Functions的SSJS实现与"本机"JavaScript区分开来.鉴于@Length(tmpStr)只是tmpStr.length的包装器,在给定足够的迭代时,Sven看到执行时间的差异并不让我感到惊讶.但是如果你的目标是优化,你可以通过将所有代码从SSJS块移动到bean方法来获得更多的改进,而不是通过避免使用@Functions来支持原生JavaScript,因为即使是本机JavaScript也必须被解析为AST.从这个意义上说,两者之间没有根本的区别.

更新:在本答案开头提到的AST解析有一点警告.默认情况下,XPage运行时缓存最多400个唯一的SSJS表达式(您可以通过ibm.jscript.cachesize服务器的xsp.properties文件中的属性覆盖此限制).因此,如果遇到的表达式与已经缓存的表达式完全匹配(包括空格),则Domino不必为该表达式构造新的AST; 它只引用缓存中已有的树.这是一个MRU("最近使用的")缓存,因此遇到相同表达式的频率越高,保留在缓存中的可能性就越大.无论AST是否被缓存,它仍然必须针对当前上下文进行评估,并且如果您只是直接使用Java进行编码(例如,与您可能使用的内容相比),一些JavaScript包装器对象确实会产生额外的开销. ,{}变成一个ObjectObject,类似于a HashMap,但具有支持闭包的附加功能,如果你不使用闭包就浪费了.)但是这个AST缓存的主要性能含义是,与大多数开发环境不同,代码重复实际上可能是一件好事,如果只是在一次又一次地使用相同的精确表达式允许除了第一个实例之外的所有实例每个都跳过语言解析并直接跳转到调用.