我希望您能够用宏来消除Scala构建下行传递函数对象的需要。这段代码在我们系统的内部循环中使用,我们不希望内部循环无休止地分配对象。这为我们创建了性能问题。
我们的原始代码是这样的:
我们的原始代码是这样的:
dis.withBitLengthLimit(newLimit){... body ...}
而且主体是作为函数对象传递的函数。
我的问题在于原始的非宏版本引用了'this'。下面的解决方法是使每个调用宏的地方将'this'对象作为另一个参数传递。即,像这样不美观:
dis.withBitLengthLimit(dis, newLimit){... body ...}
这并不糟糕,但似乎没有必要传递dis
。有更简洁的方法吗?下面是宏代码:
object IOMacros {
/**
* Used to temporarily vary the bit length limit.
*
* Implementing as a macro eliminates the creation of a downward function object every time this
* is called.
*
* ISSUE: this macro really wants to use a self reference to `this`. But when a macro is expanded
* the object that `this` represents changes. Until a better way to do this comes about, we have to pass
* the `this` object to the `self` argument, which makes calls look like:
* dis.withBitLengthLimit(dis, newLimit){... body ...}
* That looks redundant, and it is, but it's more important to get the allocation of this downward function
* object out of inner loops.
*/
def withBitLengthLimitMacro(c: Context)(self: c.Tree, lengthLimitInBits: c.Tree)(body: c.Tree) = {
import c.universe._
q"""{
import edu.illinois.ncsa.daffodil.util.MaybeULong
val ___dStream = $self
val ___newLengthLimit = $lengthLimitInBits
val ___savedLengthLimit = ___dStream.bitLimit0b
if (!___dStream.setBitLimit0b(MaybeULong(___dStream.bitPos0b + ___newLengthLimit))) false
else {
try {
$body
} finally {
___dStream.resetBitLimit0b(___savedLengthLimit)
}
true
}
}"""
}