Live data from Hacker News

Java 8: No more loops

deadcoderising.com

81–90 of 99 posts

Re: Java 8: No more loops

#81
post #80

Earlier quoted context omitted.

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.

Have they improved the implementation recently? I have not benchmarked myself, but according to [1], they are slower than the equivalent loop-based code. [1] http://arxiv.org/pdf/1406.6631v2.pdf

This paper rightly points out that there will be overhead of object creation and potentially virtual calls (though that will be very JIT dependent). That said, my cursory examination (and it was very cursory) of their benchmark for C# is that they are really benchmarking the time difference between the iterator of an IEnumerable (or maybe IList, don't have an ability to decompile it right now) and the highly optimized case of looping through an array (which is literally one of the most highly optimized tasks on modern commodity hardware).

On one hand, it does prove their point that in certain very specialized cases (looping through an array with no abstraction atop it), you will have significant performance penalties in the generic iterator case.

On the other, I'm not sure I would attribute this to LINQ. I'm reasonably certain (and in these cases the space "reasonably" represents could have a truck driven through it) if you were to write the same code as a foreach loop using the same iterator and generic collections you wouldn't see significant performance differences. I'm definitely confident in most "real world" uses, where you are already using generic collections and iterators, you should bias towards using the LINQ implementation (assuming you believe it is better code) until definitive performance testing proves otherwise. For instance, in the case of the sum of squares, that looks like classic loop unrolling optimizations not being applied which any indirection in the looping code can prevent.

Further, they show that there already exist optimization libraries that can eliminate much of the overhead.

I will say, I'm quite impressed by the java results on this benchmark.

Also, I didn't write any tests to prove any of this, so could be wildly off the mark. Further, I've spent more time than i ever wanted either hand translating or writing macros to, translate high level collections code into while loops. But that was in an extremely performance sensitive environment.

Re: Java 8: No more loops

#82
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.

You have to measure this (carefully).

My gut feeling is that assuming streams are (in the end, but without looking) based on the loops, and Java JIT has great inlining capacity, there is really no measurable difference.

Again, one actually should measure it to conclude anything.

Re: Java 8: No more loops

#83

In C#, this is significantly more elegant: public IList getDistinctTags(IEnumerable articles) { return articles.SelectMany(a => a.Tags).Distinct().ToList(); } The entire LINQ "empire" (.NET 3.5) is built on top of IEnumerable which was around since .NET 2.0. Streams seem to be very artificial; why not rely on Iterable ? Oh, and no "yield" in Java.

I find the Java version more readable.

Re: Java 8: No more loops

#84

In C#, this is significantly more elegant: public IList getDistinctTags(IEnumerable articles) { return articles.SelectMany(a => a.Tags).Distinct().ToList(); } The entire LINQ "empire" (.NET 3.5) is built on top of IEnumerable which was around since .NET 2.0. Streams seem to be very artificial; why not rely on Iterable ? Oh, and no "yield" in Java.

Yeah, I read this and immediately thought it felt like a knockoff of LINQ.

Am I the only one bowled over by the irony of this statement given the nature of C#'s genesis?

Re: Java 8: No more loops

#85
post #18

Earlier quoted context omitted.

I welcome the functional features, but I have to agree that these specific examples are ugly compared to the more familiar alternatives. Maybe this will look more readable after getting used to it, but I'd much rather be looking at Clojure or Scala for now.

Out of curiosity, could you share an example of how this compares to Clojure or Scala? I am not familiar with either.

formatted Scala code by hibikir from above in thread[0]:

    def topJavaArticle(articles:List[Article]) = articles.find(_.tags.contains("Java"))

    def javaArticles(articles:List[Article]) = articles.filter(_.tags.contains("Java"))

    def byAuthor(articles:List[Article) = articles.groupBy(_.author)
0: https://news.ycombinator.com/item?id=8874785

Re: Java 8: No more loops

#86
Here's the Haskell equivalent for anyone curious (Beware of curry[0]!):

    data Article = Article { title :: String
                           , author :: String
                           , tags :: [String]
                           } deriving (Show)
    
    articles = [ Article "Functional Java" "James Gosling" ["functional"]
               , Article "Practical java" "James Gosling" ["enterprise","architechture"]
               , Article "Imperative Haskell" "Simon P Jones" ["imperative", "purely imperative"] ]
    
    firstJavaArticle = headMay . filter (isInfixOf "Java" . title)
    
    allJavaArticles = filter (isInfixOf "Java" . title)
    
    groupArticlesByAuthor = groupBy ((==) `on` author)
    
    distinctArticleTags = nub . join . map tags
Full working code example with code imports and type signatures:

    import Data.List (isInfixOf, groupBy, nub)
    import Safe (headMay)
    import Data.Function (on)
    import Control.Monad (join)
    
    data Article = Article { title :: String
                           , author :: String
                           , tags :: [String]
                           } deriving (Show)
    
    articles :: [Article]
    articles = [ Article "Functional Java" "James Gosling" ["functional", "functional"]
               , Article "Practical java" "James Gosling" ["enterprise","architechture"]
               , Article "Imperative Haskell" "Simon P Jones" ["imperative", "purely imperative"] ]
    
    firstJavaArticle :: [Article] -> Maybe Article
    firstJavaArticle = headMay . filter (isInfixOf "Java" . title)
    
    -- implemented in terms using allJavaArticles (NOTE: This IS performant in Haskell and IIUC due to stream fusion will only iterate once. Did not verify though.)
    firstJavaArticle' :: [Article] -> Maybe Article
    firstJavaArticle' = headMay . allJavaArticles
    
    allJavaArticles :: [Article] -> [Article]
    allJavaArticles = filter (isInfixOf "Java" . title)
    
    groupArticlesByAuthor :: [Article] -> [[Article]]
    groupArticlesByAuthor = groupBy ((==) `on` author)
    
    distinctArticleTags :: [Article] -> [String]
    distinctArticleTags = nub . join . map tags
    
    main = undefined

0: http://en.wikipedia.org/wiki/Currying

http://tech.pro/tutorial/2011/functional-javascript-part-4-f....

https://www.haskell.org/haskellwiki/Currying

Re: Java 8: No more loops

#87
post #7

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

I guess this is why Microsoft diverged from the "standard" names like 'map', 'collect' and 'filter' in favour of more human-oriented SQL-like LINQ: 'select', 'where', 'toList'. I have to read the underscore.js documentation every time I am using it :(.

I'm not sure how those are supposed to be more human-oriented? I'll grant you "where" might be a slight improvement over "filter", but calling "map" "select"? I can't make sense of that even knowing what it's supposed to mean. If anything I'd assume it to be yet another synonym for filter.

Re: Java 8: No more loops

#88
post #18

Earlier quoted context omitted.

I welcome the functional features, but I have to agree that these specific examples are ugly compared to the more familiar alternatives. Maybe this will look more readable after getting used to it, but I'd much rather be looking at Clojure or Scala for now.

Out of curiosity, could you share an example of how this compares to Clojure or Scala? I am not familiar with either.

I linked a Haskell version above as well: https://news.ycombinator.com/item?id=8878421

Re: Java 8: No more loops

#90
post #75

Earlier quoted context omitted.

Out of curiosity, could you share an example of how this compares to Clojure or Scala? I am not familiar with either.

Here's a quick version in Clojure. I'm sure it can be done cleaner than this.. (def articles [{:title "title1" :author "author1" :tags #{:Java :t2 :t3}} {:title "title2" :author "author1" :tags #{:Jvxa :t2 :t3}} {:title "title3" :author "author3" :tags #{:Java :t3}}]) ;; find the first article in the collection that has the tag “Java”. (first (filter #(contains? (:tags %) :Java) articles)) ;; ==> {:tags #{:t2 :Java :…

    (group-by :author articles)
    groupBy ((==) `on` author) articles
What's wrong with cheating? :P
Post reply on HN