I was curious about performance of creation of java8 lambda instances against the same anonymous class. (Measurement performed on win32 java build 1.8.0-ea-b106). I've created very simple example and measured if java propose some optimization of new operator while create lambda expression:
static final int MEASURES = 1000000;
static interface ICallback{
void payload(int[] a);
}
/**
* force creation of anonymous class many times
*/
static void measureAnonymousClass(){
final int arr[] = {0};
for(int i = 0; i < MEASURES; ++i){
ICallback clb = new ICallback() {
#Override
public void payload(int[] a) {
a[0]++;
}
};
clb.payload(arr);
}
}
/**
* force creation of lambda many times
*/
static void measureLambda(){
final int arr[] = {0};
for(int i = 0; i < MEASURES; ++i){
ICallback clb = (a2) -> {
a2[0]++;
};
clb.payload(arr);
}
}
(Full code can be taken there: http://codepad.org/Iw0mkXhD) The result is rather predictable - lambda wins 2 times.
But really little shift to make closure shows very bad time for lambda. Anonymous class wins 10 times!
So now anonymous class looks like:
ICallback clb = new ICallback() {
#Override
public void payload() {
arr[0]++;
}
};
And lambda does as follow:
ICallback clb = () -> {
arr[0]++;
};
(Full code can be taken there: http://codepad.org/XYd9Umty )
Can anybody explain me why exists so big (bad) difference in handling of closure?
UPDATE
A few comments wondering if my benchmark at the bottom was flawed - after introducing a lot of randomness (to prevent the JIT from optimising too much stuff), I still get similar results so I tend to think it is ok.
In the meantime, I have come across this presentation by the lambda implementation team. Page 16 shows some performance figures: inner classes and closures have similar performance / non-capturing lambda are up to 5x times faster.
And #StuartMarks posted this JVMLS 2013 talk from Sergey Kuksenko on lambda performance. The bottom line is that post JIT compilation, lambdas and anonymous classes perform similarly on current Hostpot JVM implementations.
YOUR BENCHMARK
I have also run your test, as you posted it. The problem is that it runs for as little as 20 ms for the first method and 2 ms for the second. Although that is a 10:1 ratio, it is in no way representative because the measurement time is way too small.
I have then taken modified your test to allow for more JIT warmup and I get similar results as with jmh (i.e. no difference between anonymous class and lambda).
public class Main {
static interface ICallback {
void payload();
}
static void measureAnonymousClass() {
final int arr[] = {0};
ICallback clb = new ICallback() {
#Override
public void payload() {
arr[0]++;
}
};
clb.payload();
}
static void measureLambda() {
final int arr[] = {0};
ICallback clb = () -> {
arr[0]++;
};
clb.payload();
}
static void runTimed(String message, Runnable act) {
long start = System.nanoTime();
for (int i = 0; i < 10_000_000; i++) {
act.run();
}
long end = System.nanoTime();
System.out.println(message + ":" + (end - start));
}
public static void main(String[] args) {
runTimed("as lambdas", Main::measureLambda);
runTimed("anonymous class", Main::measureAnonymousClass);
runTimed("as lambdas", Main::measureLambda);
runTimed("anonymous class", Main::measureAnonymousClass);
runTimed("as lambdas", Main::measureLambda);
runTimed("anonymous class", Main::measureAnonymousClass);
runTimed("as lambdas", Main::measureLambda);
runTimed("anonymous class", Main::measureAnonymousClass);
}
}
The last run takes about 28 seconds for both methods.
JMH MICRO BENCHMARK
I have run the same test with jmh and the bottom line is that the four methods take as much time as the equivalent:
void baseline() {
arr[0]++;
}
In other words, the JIT inlines both the anonymous class and the lambda and they take exactly the same time.
Results summary:
Benchmark Mean Mean error Units
empty_method 1.104 0.043 nsec/op
baseline 2.105 0.038 nsec/op
anonymousWithArgs 2.107 0.028 nsec/op
anonymousWithoutArgs 2.120 0.044 nsec/op
lambdaWithArgs 2.116 0.027 nsec/op
lambdaWithoutArgs 2.103 0.017 nsec/op
Related
I'll want to compare the speed of work two classes (StringBuider and StringBuffer) using append method.
And I wrote very simple program:
public class Test {
public static void main(String[] args) {
try {
test(new StringBuffer("")); // StringBuffer: 35117ms.
test(new StringBuilder("")); // StringBuilder: 3358ms.
} catch (IOException e) {
System.err.println(e.getMessage());
}
}
private static void test(Appendable obj) throws IOException {
long before = System.currentTimeMillis();
for (int i = 0; i++ < 1e9; ) {
obj.append("");
}
long after = System.currentTimeMillis();
System.out.println(obj.getClass().getSimpleName() + ": " +
(after - before) + "ms.");
}
}
But I know, that it's bad way for benchmarking. I want to put the annotations on the method or class, set the number of iterations, tests, different conditions and at the output to get accurate results.
Please advise a good library or standard Java tools to solve this problem. Additionally, if not difficult, write a good benchmarking.
Thanks in advance!
JMH, the Java Microbenchmark Harness, allows to run correct micro benchmarks. It uses annotations to express benchmark parameters.
This is the sequential version:
void f(long n) {
for (int i=1; i<n-1; i++) {
// do nothing
}
}
List result = []
(1..99999).each {
f(it)
result << it
}
It takes a few seconds to run the code.
void f(long n) {
for (int i=1; i<n-1; i++) {
// do nothing
}
}
withPool {
runForkJoin(1,99999) { a, b ->
List result = []
(a..b).each {
f(it)
result << it
}
return result
}
}
The code above takes several minutes to finish. I haven't call any forkOffChild() or childrenResults() yet. I'm running this code in Windows and single core CPU with Intel Hyperthreading (2 logical CPU). Java Runtime.runtime.availableProcessors() returns 2.
I don't understand why the code that uses runForkJoin much slower than the sequential code (minutes versus seconds).
The runForJoin() method has no impact on performance in the code snippet. It is the withPool() method, that causes the slowdown. This is because the withPool() method adds several xxxParallel() methods to the Groovy Object's dynamic scope, which then slows down method resolution.
Annotating the f() method as #CompileStatic will give you the expected performance.
This is question comes in mind when I finding difference between abstract class and interface.
In this post I came to know that interfaces are slow as they required extra indirection.
But I am not getting what type of indirection required by the interface and not by the abstract class or concrete class.Please clarify on it.
Thanks in advance
There are many performance myths, and some were probably true several years ago, and some might still be true on VMs that don't have a JIT.
The Android documentation (remember that Android don't have a JVM, they have Dalvik VM) used to say that invoking a method on an interfaces was slower than invoking it on a class, so they were contributing to spreading the myth (it's also possible that it was slower on the Dalvik VM before they turned on the JIT). The documentation does now say:
Performance Myths
Previous versions of this document made various misleading claims. We
address some of them here.
On devices without a JIT, it is true that invoking methods via a
variable with an exact type rather than an interface is slightly more
efficient. (So, for example, it was cheaper to invoke methods on a
HashMap map than a Map map, even though in both cases the map was a
HashMap.) It was not the case that this was 2x slower; the actual
difference was more like 6% slower. Furthermore, the JIT makes the two
effectively indistinguishable.
Source: Designing for performance on Android
The same thing is probably true for the JIT in the JVM, it would be very odd otherwise.
If in doubt, measure it. My results showed no significant difference. When run, the following program produced:
7421714 (abstract)
5840702 (interface)
7621523 (abstract)
5929049 (interface)
But when I switched the places of the two loops:
7887080 (interface)
5573605 (abstract)
7986213 (interface)
5609046 (abstract)
It appears that abstract classes are slightly (~6%) faster, but that should not be noticeable; These are nanoseconds. 7887080 nanoseconds are ~7 milliseconds. That makes it a difference of 0.1 millis per 40k invocations (Java version: 1.6.20)
Here's the code:
public class ClassTest {
public static void main(String[] args) {
Random random = new Random();
List<Foo> foos = new ArrayList<Foo>(40000);
List<Bar> bars = new ArrayList<Bar>(40000);
for (int i = 0; i < 40000; i++) {
foos.add(random.nextBoolean() ? new Foo1Impl() : new Foo2Impl());
bars.add(random.nextBoolean() ? new Bar1Impl() : new Bar2Impl());
}
long start = System.nanoTime();
for (Foo foo : foos) {
foo.foo();
}
System.out.println(System.nanoTime() - start);
start = System.nanoTime();
for (Bar bar : bars) {
bar.bar();
}
System.out.println(System.nanoTime() - start);
}
abstract static class Foo {
public abstract int foo();
}
static interface Bar {
int bar();
}
static class Foo1Impl extends Foo {
#Override
public int foo() {
int i = 10;
i++;
return i;
}
}
static class Foo2Impl extends Foo {
#Override
public int foo() {
int i = 10;
i++;
return i;
}
}
static class Bar1Impl implements Bar {
#Override
public int bar() {
int i = 10;
i++;
return i;
}
}
static class Bar2Impl implements Bar {
#Override
public int bar() {
int i = 10;
i++;
return i;
}
}
}
An object has a "vtable pointer" of some kind which points to a "vtable" (method pointer table) for its class ("vtable" might be the wrong terminology, but that's not important). The vtable has pointers to all the method implementations; each method has an index which corresponds to a table entry. So, to call a class method, you just look up the corresponding method (using its index) in the vtable. If one class extends another, it just has a longer vtable with more entries; calling a method from the base class still uses the same procedure: that is, look up the method by its index.
However, in calling a method from an interface via an interface reference, there must be some alternative mechanism to find the method implementation pointer. Because a class can implement multiple interfaces, it's not possible for the method to always have the same index in the vtable (for instance). There are various possible ways to resolve this, but no way that is quite as efficient as simple vtable dispatch.
However, as mentioned in the comments, it probably won't make much difference with a modern Java VM implementation.
This is variation on Bozho example. It runs longer and re-uses the same objects so the cache size doesn't matter so much. I also use an array so there is no overhead from the iterator.
public static void main(String[] args) {
Random random = new Random();
int testLength = 200 * 1000 * 1000;
Foo[] foos = new Foo[testLength];
Bar[] bars = new Bar[testLength];
Foo1Impl foo1 = new Foo1Impl();
Foo2Impl foo2 = new Foo2Impl();
Bar1Impl bar1 = new Bar1Impl();
Bar2Impl bar2 = new Bar2Impl();
for (int i = 0; i < testLength; i++) {
boolean flip = random.nextBoolean();
foos[i] = flip ? foo1 : foo2;
bars[i] = flip ? bar1 : bar2;
}
long start;
start = System.nanoTime();
for (Foo foo : foos) {
foo.foo();
}
System.out.printf("The average abstract method call was %.1f ns%n", (double) (System.nanoTime() - start) / testLength);
start = System.nanoTime();
for (Bar bar : bars) {
bar.bar();
}
System.out.printf("The average interface method call was %.1f ns%n", (double) (System.nanoTime() - start) / testLength);
}
prints
The average abstract method call was 4.2 ns
The average interface method call was 4.1 ns
if you swap the order the tests are run you get
The average interface method call was 4.2 ns
The average abstract method call was 4.1 ns
There is more difference in how you run the test than which one you chose.
I got the same result with Java 6 update 26 and OpenJDK 7.
BTW: If you add a loop which only call the same object each time, you get
The direct method call was 2.2 ns
I tried to write a test that would quantify all of the various ways methods might be invoked. My findings show that it is not whether a method is an interface method or not that matters, but rather the type of the reference through which you are calling it. Calling an interface method through a class reference is much faster (relative to the number of calls) than calling the same method on the same class via an interface reference.
The results for 1,000,000 calls are...
interface method via interface reference: (nanos, millis) 5172161.0, 5.0
interface method via abstract reference: (nanos, millis) 1893732.0, 1.8
interface method via toplevel derived reference: (nanos, millis) 1841659.0, 1.8
Concrete method via concrete class reference: (nanos, millis) 1822885.0, 1.8
Note that the first two lines of the results are calls to the exact same method, but via different references.
And here is the code...
package interfacetest;
/**
*
* #author rpbarbat
*/
public class InterfaceTest
{
static public interface ITest
{
public int getFirstValue();
public int getSecondValue();
}
static abstract public class ATest implements ITest
{
int first = 0;
#Override
public int getFirstValue()
{
return first++;
}
}
static public class TestImpl extends ATest
{
int second = 0;
#Override
public int getSecondValue()
{
return second++;
}
}
static public class Test
{
int value = 0;
public int getConcreteValue()
{
return value++;
}
}
static int loops = 1000000;
/**
* #param args the command line arguments
*/
public static void main(String[] args)
{
// Get some various pointers to the test classes
// To Interface
ITest iTest = new TestImpl();
// To abstract base
ATest aTest = new TestImpl();
// To impl
TestImpl testImpl = new TestImpl();
// To concrete
Test test = new Test();
System.out.println("Method call timings - " + loops + " loops");
StopWatch stopWatch = new StopWatch();
// Call interface method via interface reference
stopWatch.start();
for (int i = 0; i < loops; i++)
{
iTest.getFirstValue();
}
stopWatch.stop();
System.out.println("interface method via interface reference: (nanos, millis)" + stopWatch.getElapsedNanos() + ", " + stopWatch.getElapsedMillis());
// Call interface method via abstract reference
stopWatch.start();
for (int i = 0; i < loops; i++)
{
aTest.getFirstValue();
}
stopWatch.stop();
System.out.println("interface method via abstract reference: (nanos, millis)" + stopWatch.getElapsedNanos() + ", " + stopWatch.getElapsedMillis());
// Call derived interface via derived reference
stopWatch.start();
for (int i = 0; i < loops; i++)
{
testImpl.getSecondValue();
}
stopWatch.stop();
System.out.println("interface via toplevel derived reference: (nanos, millis)" + stopWatch.getElapsedNanos() + ", " + stopWatch.getElapsedMillis());
// Call concrete method in concrete class
stopWatch.start();
for (int i = 0; i < loops; i++)
{
test.getConcreteValue();
}
stopWatch.stop();
System.out.println("Concrete method via concrete class reference: (nanos, millis)" + stopWatch.getElapsedNanos() + ", " + stopWatch.getElapsedMillis());
}
}
package interfacetest;
/**
*
* #author rpbarbat
*/
public class StopWatch
{
private long start;
private long stop;
public StopWatch()
{
start = 0;
stop = 0;
}
public void start()
{
stop = 0;
start = System.nanoTime();
}
public void stop()
{
stop = System.nanoTime();
}
public float getElapsedNanos()
{
return (stop - start);
}
public float getElapsedMillis()
{
return (stop - start) / 1000;
}
public float getElapsedSeconds()
{
return (stop - start) / 1000000000;
}
}
This was using the Oracles JDK 1.6_24. Hope this helps put this question to bed...
Regards,
Rodney Barbati
Interfaces are slower than abstract class as run time decision of method invocation would add little penalty of time,
However as JIT comes in picture which will take care of repeated calls of same method hence you may see the performance lag only in first call which is also very minimal,
Now for Java 8, they almost made abstract class useless by adding default & static function,
This is question comes in mind when I finding difference between abstract class and interface.
In this post I came to know that interfaces are slow as they required extra indirection.
But I am not getting what type of indirection required by the interface and not by the abstract class or concrete class.Please clarify on it.
Thanks in advance
There are many performance myths, and some were probably true several years ago, and some might still be true on VMs that don't have a JIT.
The Android documentation (remember that Android don't have a JVM, they have Dalvik VM) used to say that invoking a method on an interfaces was slower than invoking it on a class, so they were contributing to spreading the myth (it's also possible that it was slower on the Dalvik VM before they turned on the JIT). The documentation does now say:
Performance Myths
Previous versions of this document made various misleading claims. We
address some of them here.
On devices without a JIT, it is true that invoking methods via a
variable with an exact type rather than an interface is slightly more
efficient. (So, for example, it was cheaper to invoke methods on a
HashMap map than a Map map, even though in both cases the map was a
HashMap.) It was not the case that this was 2x slower; the actual
difference was more like 6% slower. Furthermore, the JIT makes the two
effectively indistinguishable.
Source: Designing for performance on Android
The same thing is probably true for the JIT in the JVM, it would be very odd otherwise.
If in doubt, measure it. My results showed no significant difference. When run, the following program produced:
7421714 (abstract)
5840702 (interface)
7621523 (abstract)
5929049 (interface)
But when I switched the places of the two loops:
7887080 (interface)
5573605 (abstract)
7986213 (interface)
5609046 (abstract)
It appears that abstract classes are slightly (~6%) faster, but that should not be noticeable; These are nanoseconds. 7887080 nanoseconds are ~7 milliseconds. That makes it a difference of 0.1 millis per 40k invocations (Java version: 1.6.20)
Here's the code:
public class ClassTest {
public static void main(String[] args) {
Random random = new Random();
List<Foo> foos = new ArrayList<Foo>(40000);
List<Bar> bars = new ArrayList<Bar>(40000);
for (int i = 0; i < 40000; i++) {
foos.add(random.nextBoolean() ? new Foo1Impl() : new Foo2Impl());
bars.add(random.nextBoolean() ? new Bar1Impl() : new Bar2Impl());
}
long start = System.nanoTime();
for (Foo foo : foos) {
foo.foo();
}
System.out.println(System.nanoTime() - start);
start = System.nanoTime();
for (Bar bar : bars) {
bar.bar();
}
System.out.println(System.nanoTime() - start);
}
abstract static class Foo {
public abstract int foo();
}
static interface Bar {
int bar();
}
static class Foo1Impl extends Foo {
#Override
public int foo() {
int i = 10;
i++;
return i;
}
}
static class Foo2Impl extends Foo {
#Override
public int foo() {
int i = 10;
i++;
return i;
}
}
static class Bar1Impl implements Bar {
#Override
public int bar() {
int i = 10;
i++;
return i;
}
}
static class Bar2Impl implements Bar {
#Override
public int bar() {
int i = 10;
i++;
return i;
}
}
}
An object has a "vtable pointer" of some kind which points to a "vtable" (method pointer table) for its class ("vtable" might be the wrong terminology, but that's not important). The vtable has pointers to all the method implementations; each method has an index which corresponds to a table entry. So, to call a class method, you just look up the corresponding method (using its index) in the vtable. If one class extends another, it just has a longer vtable with more entries; calling a method from the base class still uses the same procedure: that is, look up the method by its index.
However, in calling a method from an interface via an interface reference, there must be some alternative mechanism to find the method implementation pointer. Because a class can implement multiple interfaces, it's not possible for the method to always have the same index in the vtable (for instance). There are various possible ways to resolve this, but no way that is quite as efficient as simple vtable dispatch.
However, as mentioned in the comments, it probably won't make much difference with a modern Java VM implementation.
This is variation on Bozho example. It runs longer and re-uses the same objects so the cache size doesn't matter so much. I also use an array so there is no overhead from the iterator.
public static void main(String[] args) {
Random random = new Random();
int testLength = 200 * 1000 * 1000;
Foo[] foos = new Foo[testLength];
Bar[] bars = new Bar[testLength];
Foo1Impl foo1 = new Foo1Impl();
Foo2Impl foo2 = new Foo2Impl();
Bar1Impl bar1 = new Bar1Impl();
Bar2Impl bar2 = new Bar2Impl();
for (int i = 0; i < testLength; i++) {
boolean flip = random.nextBoolean();
foos[i] = flip ? foo1 : foo2;
bars[i] = flip ? bar1 : bar2;
}
long start;
start = System.nanoTime();
for (Foo foo : foos) {
foo.foo();
}
System.out.printf("The average abstract method call was %.1f ns%n", (double) (System.nanoTime() - start) / testLength);
start = System.nanoTime();
for (Bar bar : bars) {
bar.bar();
}
System.out.printf("The average interface method call was %.1f ns%n", (double) (System.nanoTime() - start) / testLength);
}
prints
The average abstract method call was 4.2 ns
The average interface method call was 4.1 ns
if you swap the order the tests are run you get
The average interface method call was 4.2 ns
The average abstract method call was 4.1 ns
There is more difference in how you run the test than which one you chose.
I got the same result with Java 6 update 26 and OpenJDK 7.
BTW: If you add a loop which only call the same object each time, you get
The direct method call was 2.2 ns
I tried to write a test that would quantify all of the various ways methods might be invoked. My findings show that it is not whether a method is an interface method or not that matters, but rather the type of the reference through which you are calling it. Calling an interface method through a class reference is much faster (relative to the number of calls) than calling the same method on the same class via an interface reference.
The results for 1,000,000 calls are...
interface method via interface reference: (nanos, millis) 5172161.0, 5.0
interface method via abstract reference: (nanos, millis) 1893732.0, 1.8
interface method via toplevel derived reference: (nanos, millis) 1841659.0, 1.8
Concrete method via concrete class reference: (nanos, millis) 1822885.0, 1.8
Note that the first two lines of the results are calls to the exact same method, but via different references.
And here is the code...
package interfacetest;
/**
*
* #author rpbarbat
*/
public class InterfaceTest
{
static public interface ITest
{
public int getFirstValue();
public int getSecondValue();
}
static abstract public class ATest implements ITest
{
int first = 0;
#Override
public int getFirstValue()
{
return first++;
}
}
static public class TestImpl extends ATest
{
int second = 0;
#Override
public int getSecondValue()
{
return second++;
}
}
static public class Test
{
int value = 0;
public int getConcreteValue()
{
return value++;
}
}
static int loops = 1000000;
/**
* #param args the command line arguments
*/
public static void main(String[] args)
{
// Get some various pointers to the test classes
// To Interface
ITest iTest = new TestImpl();
// To abstract base
ATest aTest = new TestImpl();
// To impl
TestImpl testImpl = new TestImpl();
// To concrete
Test test = new Test();
System.out.println("Method call timings - " + loops + " loops");
StopWatch stopWatch = new StopWatch();
// Call interface method via interface reference
stopWatch.start();
for (int i = 0; i < loops; i++)
{
iTest.getFirstValue();
}
stopWatch.stop();
System.out.println("interface method via interface reference: (nanos, millis)" + stopWatch.getElapsedNanos() + ", " + stopWatch.getElapsedMillis());
// Call interface method via abstract reference
stopWatch.start();
for (int i = 0; i < loops; i++)
{
aTest.getFirstValue();
}
stopWatch.stop();
System.out.println("interface method via abstract reference: (nanos, millis)" + stopWatch.getElapsedNanos() + ", " + stopWatch.getElapsedMillis());
// Call derived interface via derived reference
stopWatch.start();
for (int i = 0; i < loops; i++)
{
testImpl.getSecondValue();
}
stopWatch.stop();
System.out.println("interface via toplevel derived reference: (nanos, millis)" + stopWatch.getElapsedNanos() + ", " + stopWatch.getElapsedMillis());
// Call concrete method in concrete class
stopWatch.start();
for (int i = 0; i < loops; i++)
{
test.getConcreteValue();
}
stopWatch.stop();
System.out.println("Concrete method via concrete class reference: (nanos, millis)" + stopWatch.getElapsedNanos() + ", " + stopWatch.getElapsedMillis());
}
}
package interfacetest;
/**
*
* #author rpbarbat
*/
public class StopWatch
{
private long start;
private long stop;
public StopWatch()
{
start = 0;
stop = 0;
}
public void start()
{
stop = 0;
start = System.nanoTime();
}
public void stop()
{
stop = System.nanoTime();
}
public float getElapsedNanos()
{
return (stop - start);
}
public float getElapsedMillis()
{
return (stop - start) / 1000;
}
public float getElapsedSeconds()
{
return (stop - start) / 1000000000;
}
}
This was using the Oracles JDK 1.6_24. Hope this helps put this question to bed...
Regards,
Rodney Barbati
Interfaces are slower than abstract class as run time decision of method invocation would add little penalty of time,
However as JIT comes in picture which will take care of repeated calls of same method hence you may see the performance lag only in first call which is also very minimal,
Now for Java 8, they almost made abstract class useless by adding default & static function,
I know there is no direct equivalent in Java itself, but perhaps a third party?
It is really convenient. Currently I'd like to implement an iterator that yields all nodes in a tree, which is about five lines of code with yield.
The two options I know of is Aviad Ben Dov's infomancers-collections library from 2007 and Jim Blackler's YieldAdapter library from 2008 (which is also mentioned in the other answer).
Both will allow you to write code with yield return-like construct in Java, so both will satisfy your request. The notable differences between the two are:
Mechanics
Aviad's library is using bytecode manipulation while Jim's uses multithreading. Depending on your needs, each may have its own advantages and disadvantages. It's likely Aviad's solution is faster, while Jim's is more portable (for example, I don't think Aviad's library will work on Android).
Interface
Aviad's library has a cleaner interface - here's an example:
Iterable<Integer> it = new Yielder<Integer>() {
#Override protected void yieldNextCore() {
for (int i = 0; i < 10; i++) {
yieldReturn(i);
if (i == 5) yieldBreak();
}
}
};
While Jim's is way more complicated, requiring you to adept a generic Collector which has a collect(ResultHandler) method... ugh. However, you could use something like this wrapper around Jim's code by Zoom Information which greatly simplifies that:
Iterable<Integer> it = new Generator<Integer>() {
#Override protected void run() {
for (int i = 0; i < 10; i++) {
yield(i);
if (i == 5) return;
}
}
};
License
Aviad's solution is BSD.
Jim's solution is public domain, and so is its wrapper mentioned above.
Both of these approaches can be made a bit cleaner now Java has Lambdas. You can do something like
public Yielderable<Integer> oneToFive() {
return yield -> {
for (int i = 1; i < 10; i++) {
if (i == 6) yield.breaking();
yield.returning(i);
}
};
}
I explained a bit more here.
I know it's a very old question here, and there are two ways described above:
bytecode manipulation that's not that easy while porting;
thread-based yield that obviously has resource costs.
However, there is another, the third and probably the most natural, way of implementing the yield generator in Java that is the closest implementation to what C# 2.0+ compilers do for yield return/break generation: lombok-pg. It's fully based on a state machine, and requires tight cooperation with javac to manipulate the source code AST. Unfortunately, the lombok-pg support seems to be discontinued (no repository activity for more than a year or two), and the original Project Lombok unfortunately lacks the yield feature (it has better IDE like Eclipse, IntelliJ IDEA support, though).
I just published another (MIT-licensed) solution here, which launches the producer in a separate thread, and sets up a bounded queue between the producer and the consumer, allowing for buffering, flow control, and parallel pipelining between producer and consumer (so that the consumer can be working on consuming the previous item while the producer is working on producing the next item).
You can use this anonymous inner class form:
Iterable<T> iterable = new Producer<T>(queueSize) {
#Override
public void producer() {
produce(someT);
}
};
for example:
for (Integer item : new Producer<Integer>(/* queueSize = */ 5) {
#Override
public void producer() {
for (int i = 0; i < 20; i++) {
System.out.println("Producing " + i);
produce(i);
}
System.out.println("Producer exiting");
}
}) {
System.out.println(" Consuming " + item);
Thread.sleep(200);
}
Or you can use lambda notation to cut down on boilerplate:
for (Integer item : new Producer<Integer>(/* queueSize = */ 5, producer -> {
for (int i = 0; i < 20; i++) {
System.out.println("Producing " + i);
producer.produce(i);
}
System.out.println("Producer exiting");
})) {
System.out.println(" Consuming " + item);
Thread.sleep(200);
}
Stream.iterate(seed, seedOperator).limit(n).foreach(action) is not the same as yield operator, but it may be usefull to write your own generators this way:
import java.util.stream.Stream;
public class Test01 {
private static void myFoo(int someVar){
//do some work
System.out.println(someVar);
}
private static void myFoo2(){
//do some work
System.out.println("some work");
}
public static void main(String[] args) {
Stream.iterate(1, x -> x + 1).limit(15).forEach(Test01::myFoo); //var1
Stream.iterate(1, x -> x + 1).limit(10).forEach(item -> myFoo2()); //var2
}
}
I'd also suggest if you're already using RXJava in your project to use an Observable as a "yielder". It can be used in a similar fashion if you make your own Observable.
public class Example extends Observable<String> {
public static void main(String[] args) {
new Example().blockingSubscribe(System.out::println); // "a", "b", "c", "d"
}
#Override
protected void subscribeActual(Observer<? super String> observer) {
observer.onNext("a"); // yield
observer.onNext("b"); // yield
observer.onNext("c"); // yield
observer.onNext("d"); // yield
observer.onComplete(); // finish
}
}
Observables can be transformed into iterators so you can even use them in more traditional for loops. Also RXJava gives you really powerful tools, but if you only need something simple then maybe this would be an overkill.
// Java code for Stream.generate()
// to generate an infinite sequential
// unordered stream
import java.util.*;
import java.util.stream.Stream;
class GFG {
// Driver code
public static void main(String[] args) {
// using Stream.generate() method
// to generate 5 random Integer values
Stream.generate(new Random()::nextInt)
.limit(5).forEach(System.out::println);
}
}
From here.
I wrote a new library that has implemented generator for Java. It's simple, thread-free and fast.
Here is an example of generating endless fibonacci numbers:
public static Seq<Integer> fibonacci() {
return c -> {
int a = 1;
int b = 1;
c.accept(a);
c.accept(b);
while (true) {
c.accept(b = a + (a = b));
}
};
}
The Seq interface is just like Java Stream and Kotlin Sequence, but faster than all of them.
Here, let's print the first 7 elements of the fibonacci series
Seq<Integer> fib = fibonacci();
fib.take(7).printAll(","); // => 1,1,2,3,5,8,13
For the original problem, yielding all nodes of a tree? One line is enough.
Seq<Node> seq = Seq.ofTree(root, n -> Seq.of(n.left, n.right));