Performance Improvements


The Hotdog Scheme compiler is relatively simple, but it still leaves room for many enhancements. The current implementation will generate a large number of classes, one for each closure in a Scheme program. This results in larger memory overhead, as each class takes up some space in the VTABLE. Because every closure is implemented as a virtual method on a subclass of the Closure class, the VM may not be able to inline code. Furthermore, the environments lose any type information that might be deduced at compile time. All these features can be improved somewhat by extending the base implementation.

Although Hotdog treats all closures as the same, many of them can be optimized away. A closure is used to treat a body of code as a first-class object, but that is not always needed. Whenever a closure is known not to be first-class, it can be implemented as a private instance method within the enclosing closure class, sharing the same environment. Then all calls to the closure can be direct calls to the private method. This will reduce the number of closure classes and environments, replace a virtual dispatch with a direct call, and expose that method call to the JIT compiler, which may be inclined to inline it directly in the caller.

While environments coerce all their values to objects, performance can be recovered to some degree. If the compiler can infer some of the types of the environment values, it can unpack the environment and unbox small values, storing them in private instance fields. This needs to be done only in the class constructor; therefore, the performance hit will be taken only when the closure is allocated, not on every execution.

Often within a closure, the same value is repeatedly type-checked before an operation is performed. Because type checks can be expensive, repeated checks on the same value can be reduced, checks can be lifted out of loops , or, when the byte-code verifier is turned off, many can be removed completely. The last technique produces much faster code, but a program still needs some type checks. These can be optimized on the CLR by comparing the type tokens, as extracted by reflection. This will avoid the penalty, described earlier, when a type check fails.

Alternatively, all Scheme objects can be wrapped in a special class. This class could serve as a union of Scheme primitive data types, with an integer tag to discriminate among the types. Unfortunately, this technique would create a substantial allocation overhead, as every object would require two allocations : one for the value and one for the Scheme wrapper class. It might be possible, however, to use this trick just for small values. It remains to be seen whether it would deliver better performance for small values.



Programming in the .NET Environment
Programming in the .NET Environment
ISBN: 0201770180
EAN: 2147483647
Year: 2002
Pages: 146

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net