Skip to content

Instantly share code, notes, and snippets.

@guidomedina
Created June 18, 2016 21:42
Show Gist options
  • Save guidomedina/d20381b55c89c641ccdb5e277edcd1b8 to your computer and use it in GitHub Desktop.
Save guidomedina/d20381b55c89c641ccdb5e277edcd1b8 to your computer and use it in GitHub Desktop.
import sun.misc.Unsafe;
import java.lang.reflect.Field;
public class LazySetLong {
static final Unsafe unsafe;
static final long valueOffset;
volatile long o;
static {
try {
Field field = Unsafe.class.getDeclaredField("theUnsafe");
field.setAccessible(true);
unsafe = (Unsafe) field.get(null);
valueOffset = unsafe.objectFieldOffset
(LazySetLong.class.getDeclaredField("o"));
} catch (Exception e) {
throw new AssertionError(e);
}
}
/**
* @param o It is only really useful where the field is volatile, and is thus expected to change unexpectedly.
* @throws NoSuchFieldException
*/
public void lazySet(long o) throws NoSuchFieldException {
unsafe.putOrderedLong(this, valueOffset, o);
}
private long callPutOrderedLong(int times) throws NoSuchFieldException {
final long start = System.nanoTime();
for (int i = 0; i < times; i++) {
lazySet(o + 1);
}
return System.nanoTime() - start;
}
private long setTheVolatileDirectly(int times) {
final long start = System.nanoTime();
for (int i = 0; i < times; i++) {
o++;
}
return System.nanoTime() - start;
}
public static void main(String... args) throws NoSuchFieldException {
final LazySetLong that = new LazySetLong();
for (int i = 0; i < 1000; i++) {
long time1 = that.callPutOrderedLong(100_000_000);
long time2 = that.setTheVolatileDirectly(100_000_000);
System.out.printf("Loop #%,d: callPutOrderedLong() took %.3fus and setting the volatile directly took %.3fus on average, ratio=%.3f%n",
i, time1 / 1e3, time2 / 1e3, (double) time1 / time2);
}
System.out.println("\nJust printing work so that it is not optimized out, work=" + that.o);
}
}
@guidomedina
Copy link
Author

...
Loop #230: callPutOrderedLong() took 172782.618us and setting the volatile directly took 514585.054us on average, ratio=0.336
Loop #231: callPutOrderedLong() took 165486.013us and setting the volatile directly took 530974.055us on average, ratio=0.312
Loop #232: callPutOrderedLong() took 172194.930us and setting the volatile directly took 512515.784us on average, ratio=0.336
Loop #233: callPutOrderedLong() took 166592.457us and setting the volatile directly took 508037.385us on average, ratio=0.328
Loop #234: callPutOrderedLong() took 168892.725us and setting the volatile directly took 518633.835us on average, ratio=0.326
Loop #235: callPutOrderedLong() took 175407.640us and setting the volatile directly took 507120.150us on average, ratio=0.346
Loop #236: callPutOrderedLong() took 168177.391us and setting the volatile directly took 505803.219us on average, ratio=0.332
Loop #237: callPutOrderedLong() took 169617.876us and setting the volatile directly took 526652.913us on average, ratio=0.322
Loop #238: callPutOrderedLong() took 171055.937us and setting the volatile directly took 515023.645us on average, ratio=0.332
Loop #239: callPutOrderedLong() took 180316.977us and setting the volatile directly took 511591.501us on average, ratio=0.352
...

@nitsanw
Copy link

nitsanw commented Jul 22, 2016

JMH please.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment