Live data from Hacker News

Java 8: No more loops

deadcoderising.com

61–70 of 99 posts

Re: Java 8: No more loops

#61
Any thoughts on performance differences between loops and streams?

My gut says that loops, being a more primitive concept are likely to perform better in most situations. In addition I just find loops easier to reason about, but that is probably purely personal.

Re: Java 8: No more loops

#62
post #49
post #45

Earlier quoted context omitted.

The main reason they build these on Stream rather than Iterable is b/c they wanted to include the `parallel()` method, which works via "spliterators" rather than plain old iterators. In other words, in order to support a gimmick you can actually use in production in a maybe a handful of use cases, they complicated the api for the use cases you hit 99% of the time. Awesome.

actually this is not true, what you're not noticing is that the parallel() use is akin to Spark, basically these streams are just map functions and if you can put the closure onto multiple cores/machines you get much better performance without any additional programmer intelligence. If you think that api is complicated then I don't think programming is for you, this is a very ordinary and usual construct in programmi…

In the cases where your application can benefit from parallelizing simple operations over a large data set stored in a collection, `parallel()` is fine.

It's even fine in the case where you're pulling data from a file or other low-latency sequential data source, assuming that the cost of filling a spliterator buffer is less than your cost of processing.

But there's a list of gotchas all more dangerous than the "magic make it faster" button of .parallel() imply:

- For the sequential data source case, if the cost of filling the spliterator buffers is higher than the cost of processing, you're just wasting a ton of overhead trying to use parallel.

- You have to be aware that by default all uses of parallel() run on the same threadpool, which makes it a potential timebomb if someone uses it in the context of, say, a webserver where multiple requests might all individually process streams. This also means blocking operations during stream processing are very dangerous.

- Mutating an external variable goes from being fine for a sequential stream to a race condition for a parallel one.

- You can't hand out Streams that you intend to be executed sequentially, b/c your callers can just call parallel() whenever they want.

And, yes, all of these considerations make the api more complicated than one operating over plain old iterators.

Re: Java 8: No more loops

#63
post #61

Any thoughts on performance differences between loops and streams? My gut says that loops, being a more primitive concept are likely to perform better in most situations. In addition I just find loops easier to reason about, but that is probably purely personal.

I have not looked at the java8 constructs surrounding this.

This is largely implementation specific. For instance, the .net LINQ to object implementations are largely syntactic sugar around loops (that is they compile to the same thing). Similarly, for loops are frequently just syntactic sugar around while loops.

Re: Java 8: No more loops

#64
post #61

Any thoughts on performance differences between loops and streams? My gut says that loops, being a more primitive concept are likely to perform better in most situations. In addition I just find loops easier to reason about, but that is probably purely personal.

From my understanding the big win that is not discussed in the article is the parallelism. Stream operations can occur concurrently potentially improving performance.

EDIT: There is more in-depth discussion of this in this thread. I missed it.

Re: Java 8: No more loops

#65

I really want to like functional programming, but the functional version of each of these seems less readable and more verbose.

I saw a quote recently from Rich Hickey:

"Elegance and familiarity are orthogonal."

I didn't fully understand this concept until I read your post and found myself disagreeing with you, thinking "what is obstinate talking about? OBVIOUSLY the streams way is way more readable and far less verbose".

The thing is, I can't believe I'm thinking that because I was exactly in your place a few months ago. Since that time, however, I've become very familiar with functional styles and now the Java 8 streams way seems "almost, but not quite right" and the imperative iteration style seems "gratuitously complicated and philosophically wrong... I mean... look at all that special syntax! That mutation! The horror!"

All of this is to say that I'm not quite sure either of us is more correct than the other, but familiarity does seem to cause a profound mental shift.

Re: Java 8: No more loops

#67
post #61

Any thoughts on performance differences between loops and streams? My gut says that loops, being a more primitive concept are likely to perform better in most situations. In addition I just find loops easier to reason about, but that is probably purely personal.

It should be noted that one must assume a performance penalty when calling stream() on a Collection, as doing so creates a new Stream object. Within inner loops and for small Collections I recommend avoiding stream() altogether if performance is a concern. Furthermore, while tempting, Stream.parallel() should only be called when it is certain that the additional cost of a ForkJoinPool instance creation can be amortized over the duration of the lambda's runtime. With that said, I welcome Streams and other FP concepts to Java.

Re: Java 8: No more loops

#68
post #50

Earlier quoted context omitted.

If you ever want to change the implementation of Article, you'd break anyone that was using that part of your API. If you use getters, you can change your implementation without breaking the consumers of your API. For instance, let's say that you don't want to store the author's name as a string anymore, and want to store a reference to an Author object. If you have a getAuthor() method, you can change it from a simp…

Besides, getters and setters are debuggable. They allow you for setting breakpoints, adding Log calls etc... Not so in case of fields. It would be nice to have some syntax sugar for defining properties more tersely though, like in C#.

Project Lombok allows you to use annotations to create getters and setters:

  @Getter
  private String author;
  @Getter
  private String title;
Or, on the class, here with a fluent (non-JavaBean) API:

  @Data
  @Accessors(fluent = true) // experimental
  public class Article {
    private String author;
    ...
  }

Re: Java 8: No more loops

#69
post #30

why not use: public final class Article{ public final String title; public final String author; public final List tags; public Article(String title, String author, List tags) { this.title = title; this.author = author; this.tags = tags; } } Getters don't seem very useful on an immutable object.

If you ever want to change the implementation of Article, you'd break anyone that was using that part of your API. If you use getters, you can change your implementation without breaking the consumers of your API. For instance, let's say that you don't want to store the author's name as a string anymore, and want to store a reference to an Author object. If you have a getAuthor() method, you can change it from a simp…

> If you ever want to change the implementation of Article, you'd break anyone that was using that part of your API. If you use getters, you can change your implementation without breaking the consumers of your API.

Then it wouldn't be immutable, if I can change the implementation I can also create a mutable version.

Edit example

  public class Article {
      private final String title;
      private final String author;
      private final List tags;

      private Article(String title, String author, List tags) {
          this.title = title;
          this.author = author;
          this.tags = tags;
      }

      public String getTitle() {
          return title;
      }

      public String getAuthor() {
          return author;
      }

      public List getTags() {
          return tags;
      }
  }

  public class MutableArticle extends Article {
      private String title;
      private String author;
      private List tags;

      public MutableArticle() {
          super(null, null, null);
      }

      public String getTitle() {
          return title;
      }

      public void setTitle(String title) {
          this.title = title;
      }

      public String getAuthor() {
          return author;
      }

      public void setAuthor(String author) {
          this.author = author;
      }

      public List getTags() {
          return tags;
      }

      public void setTags(List tags) {
          this.tags = tags;
      }

  }

Re: Java 8: No more loops

#70
post #52
post #13

Earlier quoted context omitted.

Those aren't the worst offenders. I'm referring to curry, cadr, lambda, monad, etc. But map is confusing: it's also a data structure. "Wait, does map() create a new key-value dictionary?" Filter and collect are okay. Reduce is pretty arcane but tolerable, but the actual operation feels intuitively closer to "categorize" or "group." My point about math was cultural. Math seems to revel in having its own peculiar and o…

1. Map isn't "also a data structure" , the data structure is a way to implement a mapping function. There is no conceptual difference between code and data (for an example, see http://en.m.wikipedia.org/wiki/Cons#Not_technically_fundamen... ) 2. cadr is relatively easy, if you know your assembly ( http://en.m.wikipedia.org/wiki/Car_and_cdr#Etymology ) :-) And math has locally defined terms because one cannot give eve…

>> 2. cadr is relatively easy, if you know your assembly (http://en.m.wikipedia.org/wiki/Car_and_cdr#Etymology) :-)

If you know IBM 704 assembly...

Post reply on HN