Java
Performance layer
Write performance measurement with JMH and GC tuning.
The performance measurement layer
The performance layer wraps the reactive publish with timing. A TimedPublisher wraps a SimplePublisher delegate; publish takes System.nanoTime() before and after and computes the elapsed time. This is the decorator pattern.
Since the timing varies, instead of printing the raw duration we print a fixed marker that says the measurement was done. This keeps the output deterministic.
The decorator pattern
Before wrapping SimplePublisher, TimedPublisher takes it in its constructor and stores it in a delegate field. When publish is called it first measures, then calls the delegate's publish. This is the decorator pattern: it changes object behaviour by wrapping.
The decorator uses composition instead of inheritance. That makes it flexible; it can wrap any publisher.
Exercise Write the TimedPublisher class
Add a class TimedPublisher to the structure above with a SimplePublisher delegate field and a TimedPublisher(SimplePublisher delegate) constructor. Its void publish(String item) method first does long start = System.nanoTime();, then delegate.publish(item);, then long elapsed = System.nanoTime() - start; and prints System.out.println("elapsed measured: " + (elapsed >= 0));. In main create SimplePublisher p = new SimplePublisher();, add a subscriber and call new TimedPublisher(p).publish("hello");.
Show example solution
@interface Service {}
@Service
class HelloService {
String greet() { return "hello"; }
}
interface Subscriber {
void onNext(String item);
}
class SimplePublisher {
java.util.List<Subscriber> subs = new java.util.ArrayList<>();
void subscribe(Subscriber s) { subs.add(s); }
void publish(String item) {
for (Subscriber s : subs) s.onNext(item);
}
}
class TimedPublisher {
SimplePublisher delegate;
TimedPublisher(SimplePublisher delegate) {
this.delegate = delegate;
}
void publish(String item) {
long start = System.nanoTime();
delegate.publish(item);
long elapsed = System.nanoTime() - start;
System.out.println("elapsed measured: " + (elapsed >= 0));
}
}
public class Main {
public static void main(String[] args) {
SimplePublisher p = new SimplePublisher();
p.subscribe(s -> System.out.println("got: " + s));
new TimedPublisher(p).publish("hello");
}
}
Test yourself
-
What does the performance layer measure?
- Publish duration
- Memory address
- Disk space
- Thread count
Show answer
Publish duration — TimedPublisher measures the elapsed time of the publish.
-
Complete the timing call
long start = System.____;
Show answer
long start = System.nanoTime();
-
Match the performance elements
- nanoTime
- High-resolution clock
- TimedPublisher
- Timing wrapper
- delegate
- Wrapped publisher
- decorator
- Wrapping pattern
Next lesson: Microservice basics