blob: 44686990476c17698eba5adf54d838b1c58f3e08 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.ode.jacob.vpu;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import junit.framework.TestCase;
import org.apache.ode.jacob.oo.Channel;
import org.apache.ode.jacob.oo.ChannelProxy;
public class ProxyConstructorTimingTest extends TestCase {
private static final long COUNT = 1000000L;
public ProxyConstructorTimingTest(String testName) {
super(testName);
}
public void testDoNothing() throws Exception {
Greeter gp = (Greeter) Proxy.newProxyInstance(Greeter.class.getClassLoader(),
new Class<?>[] {ChannelProxy.class, Greeter.class}, new GreeterInvocationHandler(new GreeterImpl()));
assertEquals("Hello World", gp.hello("World"));
}
public interface TestExecution {
public void execute() throws Exception;
}
public class RepeatExecution implements TestExecution {
private final long count;
private final TestExecution test;
public RepeatExecution(long count, TestExecution test) {
this.count = count;
this.test = test;
}
public void execute() throws Exception {
for (long i = 0; i < count; i++) {
test.execute();
}
}
}
public class TimedExecution implements TestExecution {
private final String name;
private final TestExecution test;
public TimedExecution(String name, TestExecution test) {
this.name = name;
this.test = test;
}
public void execute() throws Exception {
NanoTimer timer = new NanoTimer().start();
test.execute();
System.out.println("TimedExecution(" + name + "): " + timer.stop() + "[ns]");
}
}
public void timedRepeatedExecution(String name, TestExecution test) throws Exception {
new TimedExecution(name, new RepeatExecution(COUNT, test)).execute();
}
public void manualTestProxyTiming() throws Exception {
timedRepeatedExecution("direct invocation", new TestExecution() {
public void execute() throws Exception {
// Create new instance every time
new GreeterImpl2().hello("World");
}
});
timedRepeatedExecution("newProxyInstance", new TestExecution() {
public void execute() throws Exception {
Greeter gp = (Greeter) Proxy.newProxyInstance(Greeter.class.getClassLoader(),
new Class<?>[] {Greeter.class}, new GreeterInvocationHandler(new GreeterImpl2()));
gp.hello("World");
}
});
final ProxyConstructor<Greeter> helper = new ProxyConstructor<Greeter>(Greeter.class);
timedRepeatedExecution("ProxyConstructor", new TestExecution() {
public void execute() throws Exception {
Greeter gp = (Greeter) helper.newInstance(new GreeterInvocationHandler(new GreeterImpl2()));
gp.hello("World");
}
});
}
public interface Greeter extends Channel {
String hello(String name);
}
@SuppressWarnings("serial")
public class GreeterImpl implements Greeter {
public String hello(String name) {
return "Hello " + name;
}
}
@SuppressWarnings("serial")
public class GreeterImpl2 implements Greeter {
public String hello(String name) {
return "";
}
}
public class GreeterInvocationHandler implements InvocationHandler {
private Object greeter;
GreeterInvocationHandler(Object o) {
greeter = o;
}
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
if(Object.class == method.getDeclaringClass()) {
String name = method.getName();
if("equals".equals(name)) {
return proxy == args[0];
} else if("hashCode".equals(name)) {
return System.identityHashCode(proxy);
} else if("toString".equals(name)) {
return proxy.getClass().getName() + "@" +
Integer.toHexString(System.identityHashCode(proxy)) +
", with InvocationHandler " + this;
} else {
throw new IllegalStateException(String.valueOf(method));
}
}
return method.invoke(greeter, args);
}
}
// TODO: may be useful for other things? move it somewhere else?
public class NanoTimer {
private long start;
private long lap;
// TODO: we could also count laps...
public NanoTimer() {
// don't start by default, easy to just call .start();
}
public NanoTimer start() {
start = System.nanoTime();
lap = start;
return this;
}
public long stop() {
long span = System.nanoTime() - start;
start = 0;
lap = 0;
return span;
}
public long lap() {
long prev = lap;
lap = (start != 0) ? System.nanoTime() : 0;
return lap - prev;
}
}
}