Skip to content

Instantly share code, notes, and snippets.

@akarnokd
Created August 9, 2017 11:13
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save akarnokd/64430b072e7f042a8be8b1e476efb383 to your computer and use it in GitHub Desktop.
Save akarnokd/64430b072e7f042a8be8b1e476efb383 to your computer and use it in GitHub Desktop.
import org.openjdk.jmh.annotations.*;
import java.lang.invoke.*;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicReference;
@BenchmarkMode(Mode.Throughput)
@Warmup(iterations = 5)
@Measurement(iterations = 5, time = 1, timeUnit = TimeUnit.SECONDS)
@OutputTimeUnit(TimeUnit.SECONDS)
@Fork(value = 1)
@State(Scope.Thread)
public class VarHandleCostPerf {
AtomicReference<Flow.Subscription> z = new AtomicReference<>() { };
AtomicReference<Flow.Subscription> y = new AtomicReference<>() { };
AtomicReference<Flow.Subscription> x = new AtomicReference<>() { };
AtomicReference<Flow.Subscription> w = new AtomicReference<>() { };
AtomicReference<Flow.Subscription> v = new AtomicReference<>() { };
AtomicReference<Flow.Subscription> u = new AtomicReference<>() { };
AtomicReference<Flow.Subscription> t = new AtomicReference<>() { };
A a = new A();
B b = new B();
C c = new C();
D d = new D();
E e = new E();
F f = new F();
G g = new G();
@Benchmark
public void baseline1() {
AtomicReference<Flow.Subscription> t = this.t;
cancel(t);
t.setPlain(null);
}
@Benchmark
public void baseline2() {
cancel(t);
cancel(u);
t.setPlain(null);
u.setPlain(null);
}
@Benchmark
public void baseline3() {
cancel(t);
cancel(u);
cancel(v);
t.setPlain(null);
u.setPlain(null);
v.setPlain(null);
}
@Benchmark
public void baseline4() {
cancel(t);
cancel(u);
cancel(v);
cancel(w);
t.setPlain(null);
u.setPlain(null);
v.setPlain(null);
w.setPlain(null);
}
@Benchmark
public void baseline5() {
cancel(t);
cancel(u);
cancel(v);
cancel(w);
cancel(x);
t.setPlain(null);
u.setPlain(null);
v.setPlain(null);
w.setPlain(null);
x.setPlain(null);
}
@Benchmark
public void baseline6() {
cancel(t);
cancel(u);
cancel(v);
cancel(w);
cancel(x);
cancel(y);
t.setPlain(null);
u.setPlain(null);
v.setPlain(null);
w.setPlain(null);
x.setPlain(null);
y.setPlain(null);
}
@Benchmark
public void baseline7() {
cancel(t);
cancel(u);
cancel(v);
cancel(w);
cancel(x);
cancel(y);
cancel(z);
t.setPlain(null);
u.setPlain(null);
v.setPlain(null);
w.setPlain(null);
x.setPlain(null);
y.setPlain(null);
z.setPlain(null);
}
@Benchmark
public void bench1() {
a.cancel();
a.upstream = null;
}
@Benchmark
public void bench2() {
a.cancel();
b.cancel();
a.upstream = null;
b.upstream = null;
}
@Benchmark
public void bench3() {
a.cancel();
b.cancel();
c.cancel();
a.upstream = null;
b.upstream = null;
c.upstream = null;
}
@Benchmark
public void bench4() {
a.cancel();
b.cancel();
c.cancel();
d.cancel();
a.upstream = null;
b.upstream = null;
c.upstream = null;
d.upstream = null;
}
@Benchmark
public void bench5() {
a.cancel();
b.cancel();
c.cancel();
d.cancel();
e.cancel();
a.upstream = null;
b.upstream = null;
c.upstream = null;
d.upstream = null;
e.upstream = null;
}
@Benchmark
public void bench6() {
a.cancel();
b.cancel();
c.cancel();
d.cancel();
e.cancel();
f.cancel();
a.upstream = null;
b.upstream = null;
c.upstream = null;
d.upstream = null;
e.upstream = null;
f.upstream = null;
}
@Benchmark
public void bench7() {
a.cancel();
b.cancel();
c.cancel();
d.cancel();
e.cancel();
f.cancel();
g.cancel();
a.upstream = null;
b.upstream = null;
c.upstream = null;
d.upstream = null;
e.upstream = null;
f.upstream = null;
g.upstream = null;
}
static final class A {
Flow.Subscription upstream;
static final VarHandle UPSTREAM;
static {
try {
UPSTREAM = MethodHandles.lookup().findVarHandle(A.class, "upstream", Flow.Subscription.class);
} catch (Throwable ex) {
throw new InternalError(ex);
}
}
void cancel() {
VarHandleCostPerf.cancel(this, UPSTREAM);
}
}
static final class B {
Flow.Subscription upstream;
static final VarHandle UPSTREAM;
static {
try {
UPSTREAM = MethodHandles.lookup().findVarHandle(B.class, "upstream", Flow.Subscription.class);
} catch (Throwable ex) {
throw new InternalError(ex);
}
}
void cancel() {
VarHandleCostPerf.cancel(this, UPSTREAM);
}
}
static final class C {
Flow.Subscription upstream;
static final VarHandle UPSTREAM;
static {
try {
UPSTREAM = MethodHandles.lookup().findVarHandle(C.class, "upstream", Flow.Subscription.class);
} catch (Throwable ex) {
throw new InternalError(ex);
}
}
void cancel() {
VarHandleCostPerf.cancel(this, UPSTREAM);
}
}
static final class D {
Flow.Subscription upstream;
static final VarHandle UPSTREAM;
static {
try {
UPSTREAM = MethodHandles.lookup().findVarHandle(D.class, "upstream", Flow.Subscription.class);
} catch (Throwable ex) {
throw new InternalError(ex);
}
}
void cancel() {
VarHandleCostPerf.cancel(this, UPSTREAM);
}
}
static final class E {
Flow.Subscription upstream;
static final VarHandle UPSTREAM;
static {
try {
UPSTREAM = MethodHandles.lookup().findVarHandle(E.class, "upstream", Flow.Subscription.class);
} catch (Throwable ex) {
throw new InternalError(ex);
}
}
void cancel() {
VarHandleCostPerf.cancel(this, UPSTREAM);
}
}
static final class F {
Flow.Subscription upstream;
static final VarHandle UPSTREAM;
static {
try {
UPSTREAM = MethodHandles.lookup().findVarHandle(F.class, "upstream", Flow.Subscription.class);
} catch (Throwable ex) {
throw new InternalError(ex);
}
}
void cancel() {
VarHandleCostPerf.cancel(this, UPSTREAM);
}
}
static final class G {
Flow.Subscription upstream;
static final VarHandle UPSTREAM;
static {
try {
UPSTREAM = MethodHandles.lookup().findVarHandle(G.class, "upstream", Flow.Subscription.class);
} catch (Throwable ex) {
throw new InternalError(ex);
}
}
void cancel() {
VarHandleCostPerf.cancel(this, UPSTREAM);
}
}
public static boolean cancel(AtomicReference<Flow.Subscription> field) {
Flow.Subscription a = field.getAcquire();
if (a != CANCELLED) {
a = field.getAndSet(CANCELLED);
if (a != CANCELLED) {
if (a != null) {
a.cancel();
}
return true;
}
}
return false;
}
public static boolean cancel(Object target, VarHandle upstream) {
Flow.Subscription a = (Flow.Subscription)upstream.getAcquire(target);
if (a != CANCELLED) {
a = (Flow.Subscription)upstream.getAndSet(target, CANCELLED);
if (a != CANCELLED) {
if (a != null) {
a.cancel();
}
return true;
}
}
return false;
}
static final Flow.Subscription CANCELLED = new Flow.Subscription() {
@Override
public void request(long n) {
}
@Override
public void cancel() {
}
};
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment