我们可以对函数{{simple-ident?}},{{qualified-ident?}},{{simple-symbol?}},{{qualified-symbol?}},{{simple-keyword?}}和{{qualified-keyword?}}做出一些优化。
可以完成两项独立优化。
在{{boolean}}被使用的地方(合格的函数),我们可以改用{{some?}}以提高速度
(boolean (and (symbol? x) (namespace x) true))
可以简化为
(and (symbol? x) (some? (namespace x)))
当前专注于V8,对于
(simple-benchmark [x 'a/b f #(qualified-symbol? x)] (f) 100000000)
并减去基准成本的
(simple-benchmark [x 'a/b f (fn [] x)] (f) 100000000)
这会带来1.74的速度提升。
由于我们知道在应用{{namespace}}时我们处理的是关键词或符号,因此我们可以再使用{{(.-ns x)}}。
仅此就提供了2.21的速度提升,如果结合之前的优化作为
(and (symbol? x) (some? (.-ns x)))
我们将看到接近无穷的组合速度提升(操作有效变得免费,与基线所需时间相同)。
请注意,我们可以可能使用由谓词触发的类型推断以及一个新的宏,该宏发出{{.-ns}}而不是{{namespace}},但CLJS-2866目前依赖于在一个{{if}}测试中查看,而上述表达式像这样会导致带有短路{{&&}}的优化{{js*}}输出。
这些优化会很好,因为这些函数通常用于基于规范的生成代码测试中,其中性能可能是一个问题。
我们已在{{cljs.predicates-test}}中对这些函数进行了测试覆盖。
以下是对于{{qualified-symbol?}}当前生成的JavaScript代码供参考
function cljs$core$qualified_symbol_QMARK_(x) {
return cljs.core.boolean$(
(function() {
var and__8540__auto__ = x instanceof cljs.core.Symbol;
if (and__8540__auto__) {
var and__8540__auto____$1 = cljs.core.namespace(x);
if (cljs.core.truth_(and__8540__auto____$1)) {
return true;
} else {
return and__8540__auto____$1;
}
} else {
return and__8540__auto__;
}
})()
);
}
以下是对修订本所获得的代码
function cljs$user$qualified_symbol_QMARK_(x) {
return x instanceof cljs.core.Symbol && !(x.ns == null);
}
(该修订实现的紧凑性意味着它可能进一步内联,从而为整个程序优化带来更多的速度提升。)