Beginning with version 8 Esper has a compiler and runtime architecture. With version 8 Esper is a language, a language compiler and a runtime environment.
The Esper language is the Event Processing Language (EPL). It is a declarative, data-oriented language for dealing with high frequency time-based event data. EPL is compliant to the SQL-92 standard and extended for analyzing series of events and in respect to time.
The Esper compiler compiles EPL source code into Java Virtual Machine (JVM) bytecode so that the resulting executable code runs on a JVM within the Esper runtime environment.
The Esper runtime runs on top of a JVM. You can run byte code produced by the Esper compiler using the Esper runtime.
The Esper architecture is similar to that of other programming languages that are compiled to JVM bytecode, such as Scala, Clojure and Kotlin for example. Esper EPL however is not an imperative (procedural) programming language.
Runtime - Better performance
The Esper-8 compiler produces byte code that has better performance executing queries in the runtime. The compiler produces byte code for select-clauses, result-set-building, all expressions and event properties and much more. This removes virtual calls as interface calls are replaced by just byte code. The Esper compiler also removes certain down casting and branching that would otherwise need to be done.
Since the Esper-8 compiler produces byte code this gives the JVM a chance to use JIT (just-in-time) to produce native machine code, remove null checks, inline methods, predict branches etc..
Runtime - Uses less heap memory
For aggregations the Esper-8 compiler produces a custom aggregation row class that has fields which represent the aggregation state. Therefore each aggregation row does not have additional objects to represent things like averages or sums and instead things like average and sum in Esper-8 are simply a bunch of fields on the same object. Since aggregations are often used with group-by and since the runtime may be tracking a lot of rows, it is nice that the number of objects per row is always one for Esper-8. For Esper-7 the number of objects per row would be one object per row and one object for each value in the row.
When the Esper-8 compiler produces byte code it discards any intermediary representation of the EPL. The compiler discards all things like the abstract syntax tree (AST) that resulted from parsing EPL. It discards all the expression trees which represent the different expressions. It discards any statement specification objects and the query plan. All this intermediary information now results in byte code.
The JVM loads the byte code that the EPL compiler produced into a separate "classes" space and does not use heap. In Esper-8 there is only a small amount of EPL metadata that uses heap. JVM byte code is compact and space-efficient.
Runtime - Removes runtime library dependencies
The Esper-8 runtime only needs the SLF4J logging framework and has no other library dependencies. Keeping the runtime small, clean and embeddable is the advantage.
Runtime - Recovery performance
The Esper-8 compiler produces byte code that can be saved to a jar file. When recovering a system the byte code is already available and ready for loading into a runtime. This cuts recovery time dramatically because it eliminates the compiler steps of parsing, walking, validating and query planning. On recovery the Esper-8 runtime can simply load existing classes and initialize. This works well together with EsperHA which also loads only metadata at recovery time and since EsperHA loads state lazily when needed after a recovery.
Compiler performance
The Esper-8 compiler is a stateless service that can compile in parallel and with multiple threads. The Esper-7 architecture did not allow parallel operations in respect to compiling. The Esper-8 compiler can compile any number of EPL modules in parallel (as long as they are not interdependent).
Separation of concerns
The Esper-8 compiler can compile EPL in a process or system that is separate from the runtime thus eliminating the possibility of impacting a running system.
Before Esper-8 there was no way to fully validate EPL without deploying. With Esper-8 the validation/compilation and deployment are well separated.
Artifact management
The Esper-8 compiler produces byte code and jar files. This enables managing and deploying jar files using build tools and repositories.
Tools - Improved use with JVM profiler tools
As JVM profiler tools can instrument byte code the profiler tool reporting is more relevant.
Multi-tenancy related functionality
The compiler architecture provides a clean strategy for name management and managing dependencies between EPL modules as compiling and deploying are steps that can be separated in time and on different systems. The Esper-8 compiler and runtime allow modules to have their own namespace thus preventing name conflicts. With Esper-8 there is now explicit management of inter-module dependencies on EPL-objects such as event types, named window and others.