Re: [Haskell] [Fwd: Re: Computer Language Shootout]

simonmarhaskell:
Forwarding on behalf of Andrzej Jaworski
: -------- Original Message -------- From: Andrzej Jaworski
Dear fellows,
It is ironic that just after SPJ disclosed Comments from Brent Fulgham on Haskell and the shootout the situation has radically changed for the worse. Without knowing that I committed a blunder referring to the damn benchmark http://shootout.alioth.debian.org/gp4/benchmark.php?test=all&lang=all together with multicore support arguments when trying to convert a prominent OCaml programmer to Haskell. Now they know more of us:-)
What a language it is that jumps 30% up and down on benchmark while other languages gracefully stay in line? Can any of you explain the reason for this disgraceful degradation in Computer Language Shootout?
The degradation is due to two things: * several entries have been disqualified (some fairly, some unfairly) Fix: fix is to submit more * the shootout haskellers stopped submitting once it was clear we'd need bytestrings to do signifcantly better. Fix: bytestring is now on the shootout machine, so we can resume I don't think there is any fundamental issue exposed, other than that we stopped updating entries, while other languages decided they should try harder. If people want to contribute, improve (or write) ByteString based versions for the slow running String programs, upload them to the wiki, and to the shootout page, http://www.haskell.org/haskellwiki/Shootout For things that have been disqualified, correct the errors, and resubmit. -- Don

On 1/25/07, Donald Bruce Stewart
The degradation is due to two things:
* several entries have been disqualified (some fairly, some unfairly) Fix: fix is to submit more
* the shootout haskellers stopped submitting once it was clear we'd need bytestrings to do signifcantly better.
Fix: bytestring is now on the shootout machine, so we can resume
I don't think there is any fundamental issue exposed, other than that we stopped updating entries, while other languages decided they should try harder.
I have to disagree with this. That is, I don't object to Don's explanation of why the shootout entries degraded in this particular case, but I do think that Andrzej was right to point this out: "Perhaps making a collective effort towards benchmarking Haskell programs and analyzing the results in some methodic way could prove helpful?" and I think that he *is* pointing out a fundamental issue here. Maybe it's just me, but as someone who has some amount of experience with implementing optimizations for Haskell, I find it nearly impossible to precisely understand and measure exactly how those optimizations improve (or degrade) program performance. The tools we have just aren't adequate. And so, at least for me, implementing optimizations feels more like fumbling around in the dark than like using anything approaching the scientific method. This is, of course, because everybody has limited resources and implementing good profiling tools for implementors hasn't been a high priority. And Alexey Rodriguez's recent work on using hardware counters is a step in the right direction. But, I think the time is now to put more effort into profiling and benchmarks for Haskell. Cheers, Kirsten -- Kirsten Chevalier* chevalier@alum.wellesley.edu *Often in error, never in doubt "I wish people weren't so set on being themselves, when that means being a bastard." -- Robertson Davies

Hi
I have to disagree with this. That is, I don't object to Don's explanation of why the shootout entries degraded in this particular case, but I do think that Andrzej was right to point this out: "Perhaps making a collective effort towards benchmarking Haskell programs and analyzing the results in some methodic way could prove helpful?" and I think that he *is* pointing out a fundamental issue here.
We have the nofib suite, it could do with some attention, but it is (or was) a pretty good performance tester.
Maybe it's just me, but as someone who has some amount of experience with implementing optimizations for Haskell, I find it nearly impossible to precisely understand and measure exactly how those optimizations improve (or degrade) program performance.
The problem is that something like GHC is very complex, with lots of transformations. When transformations are firing other transformations, which in turn fire other transformations, it doesn't take a great deal to disrupt this flow of optimisation and end up with a result which doesn't accurately reflect the particular change you made. Better knowledge of the end effects on a program isn't necessarily going to translate to better knowledge of the optimisations effect. Maybe if we had a greater number and variety of optimising compilers we'd be able to more freely experiment with optimisation techniques in different settings. At the moment GHC is all there is (with Jhc not ready for mainstream use yet) Thanks Neil

On 1/25/07, Neil Mitchell
We have the nofib suite, it could do with some attention, but it is (or was) a pretty good performance tester.
Yes, I've spent enough time staring at nofib results that I understand just how random and un-representative the programs in nofib are. nofib consists of whatever people have submitted for nofib, and moreover, its contents are more or less the same now as they were in 2002. A lot has changed about the ways in which people use Haskell in those past four years -- in 2002, GHC was the only big Haskell application out there, and I don't think that's true anymore. So personally, I have zero faith in nofib results to tell me anything about how helpful optimizations will be except on a very large scale of granularity.
The problem is that something like GHC is very complex, with lots of transformations. When transformations are firing other transformations, which in turn fire other transformations, it doesn't take a great deal to disrupt this flow of optimisation and end up with a result which doesn't accurately reflect the particular change you made. Better knowledge of the end effects on a program isn't necessarily going to translate to better knowledge of the optimisations effect.
Sorry for being unclear. I agree with your comments on GHC, and one thing I was suggesting was that somebody should think about profiling tools for improving our understanding of how those transformations interact with each other, not just profiling tools for understanding the end result. Everyone says that optimization is a black art, but I remain to be convinced that understanding the interactions between different optimizations isn't a problem that would submit to appropriate amounts of effort.
Maybe if we had a greater number and variety of optimising compilers we'd be able to more freely experiment with optimisation techniques in different settings. At the moment GHC is all there is (with Jhc not ready for mainstream use yet)
I agree that there should be more diversity in compilers, but I think even sticking to GHC, there's a lot that could be done when it comes to improving understanding of just what the optimizer is doing. Anything better than staring at intermediate code would be an improvement, since time spent staring at intermediate code usually is time spent narrowing down the 2 lines out of 1000 that are relevant. Maybe it's possible to design tools that could help with that narrowing-down process. Cheers, Kirsten -- Kirsten Chevalier* chevalier@alum.wellesley.edu *Often in error, never in doubt "by God I *KNOW* what this network is for, and you can't have it."--Russ Allbery

On Thu, 25 Jan 2007, Kirsten Chevalier wrote:
Anything better than staring at intermediate code would be an improvement, since time spent staring at intermediate code usually is time spent narrowing down the 2 lines out of 1000 that are relevant. Maybe it's possible to design tools that could help with that narrowing-down process.
I suspect a structure editor would be a good start - from there it's easier to start looking at visualisations both of the code itself and the result of queries on it, and if you bolt on hs-plugins to the side I imagine a library of commonly-used queries would arise over time. -- flippa@flippac.org A problem that's all in your head is still a problem. Brain damage is but one form of mind damage.

Hi
Sorry for being unclear. I agree with your comments on GHC, and one thing I was suggesting was that somebody should think about profiling tools for improving our understanding of how those transformations interact with each other, not just profiling tools for understanding the end result.
That would be very neat. Another neat trick would be generalising optimisations so that there are fewer and more independant passes, this would make it easier to understand (and is what I was working on for Yhc).
I agree that there should be more diversity in compilers, but I think even sticking to GHC, there's a lot that could be done when it comes to improving understanding of just what the optimizer is doing. Anything better than staring at intermediate code would be an improvement, since time spent staring at intermediate code usually is time spent narrowing down the 2 lines out of 1000 that are relevant.
Yhc has intermediate code that is substantially more Haskell like, and with the command: loadCore "file.ycr" >>= writeFile "file.html" . coreHtml You can generate an active Html document that lets you explore the Core in a more interactive way - including hyperlinks for function names, syntax hilighting etc. i.e: http://www.cs.york.ac.uk/fp/yhc/Roman.html All of these things make playing with Yhc Core much more fun than playing with GHC Core. There is absolutely no reason you couldn't add all these things to GHC Core, then perhaps you'd save some time when it does come to the "examine core" level. Thanks Neil

Neil Mitchell wrote:
That would be very neat. Another neat trick would be generalising optimisations so that there are fewer and more independant passes, this would make it easier to understand (and is what I was working on for Yhc).
Well, it's the nature of repeatedly applying local reductions that you will neither really know what's going nor truly understand how to improve it. One particular example is the GHC rules mechanism. It's much better than doing nothing, but it often fails to fuse yet another list. I think that one can only achieve deterministic optimization by carefully choosing and exploiting the type system of the intermediate language. For instance, short cut fusion and strictness analysis can be expressed as type inference. If you have an intermediate language where things like boxing and forcing of thunks is explicit and typed, you have a chance to eliminate such expensive constructs by type inference and conventional inlining magic. One point is that local optimization is hard to extend across the boundaries imposed by recursion and the fixed point combinator. But I can imagine that switching to a core language with non-totality (lifted types) manifest in the types, like System F with a fixed point combinator fix :: Pointed a => (a -> a) -> a is key to crossing this boundary.
Yhc has intermediate code that is substantially more Haskell like, and with the command:
loadCore "file.ycr" >>= writeFile "file.html" . coreHtml
You can generate an active Html document that lets you explore the Core in a more interactive way - including hyperlinks for function names, syntax hilighting etc.
i.e: http://www.cs.york.ac.uk/fp/yhc/Roman.html
All of these things make playing with Yhc Core much more fun than playing with GHC Core. There is absolutely no reason you couldn't add all these things to GHC Core, then perhaps you'd save some time when it does come to the "examine core" level.
Wow, the core looks really cool! One look and you see it all. I would even rename the local variables to single letters like a,b,c because the cryptic numbers are quite hard to track. This is something coreHtml can do. Also, I'd add more color, like making punctuation marks grey, but that's a very personal taste. Concerning the shootout, it deserves much laud for it is certainly not an easy task to set it up for so many language and it keep running. But I'm not very fond of the benchmarks themselves. The goal seems to be to measure how fast different languages can execute a hard wired algorithm which specifies memory management and data layout. While this is a valid goal, I don't think it is a worthy one. It simply does not get to the interesting facts, namely how fast the natural algorithms for each language are. It just compares highly artificial algorithm implementations. Random examples are the nsieves ("count the prime numbers from 2 to M [...] create a sequence of M boolean flags") and the k-nucleotide ("define a procedure/function to update a hashtable of k-nucleotide keys") benchmarks. Both boolean flags and hash tables are completely alien to Haskell. The former would be naturally implemented by a list of primes, the latter naturally with a generalized trie. Of course, disallowing unboxed arrays will certainly move Haskell down the ranking. But what do we gain from unlimited array necromancy? Do we get a fair account on how fast and short day to day Haskell really is? And how to tweak the compilers to make day to day Haskell an even more pleasant experience? I think not. (Do not misunderstand me, ByteStrings are fine for it is the purely functional style that counts). And sorry, but using the number of gzipped bytes for comparing the code length is just ridiculous. Regards, apfelmus

Hi
Yhc has intermediate code that is substantially more Haskell like, and with the command:
Wow, the core looks really cool! One look and you see it all. I would even rename the local variables to single letters like a,b,c because the cryptic numbers are quite hard to track. This is something coreHtml can do. Also, I'd add more color, like making punctuation marks grey, but that's a very personal taste.
Yhc.Core is a big library of "useful things to do with Yhc Core". One of them is: uniqueBoundVarsWith :: [String] -> CoreExpr -> CoreExpr Which replaces the free variables with a list you pick. This means that the transformation you want is a single line: applyBodyCore (uniqueBoundVarsWith (map (:[]) ['a'..])) That will transform a whole Core program, giving you the variables you requested. That's one of the things I like about Yhc.Core, it is a very nice library to use. Thanks Neil

Neil Mitchell wrote:
The problem is that something like GHC is very complex, with lots of transformations. When transformations are firing other transformations, which in turn fire other transformations, it doesn't take a great deal to disrupt this flow of optimisation and end up with a result which doesn't accurately reflect the particular change you made. Better knowledge of the end effects on a program isn't necessarily going to translate to better knowledge of the optimisations effect.
Maybe if we had a greater number and variety of optimising compilers we'd be able to more freely experiment with optimisation techniques in different settings. At the moment GHC is all there is (with Jhc not ready for mainstream use yet)
Thanks
Neil _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Although there may not be a lot of optimizing Haskell compilers, there are compilers for languages similar to Haskell that consistently perform well. One could point to O'caml or others in the ML family, or even more interesting is the case of Clean, whose syntax heavily borrows from Haskell. What do the Clean folks do that has made their compiler so consistently competitive? Is it the abc machine? Frankly I'm amazed that a three stack based virtual machine can be translated into such efficient machine code in register centric CPU architecture. Can Haskell compiler writers learn something from this? Supposedly someone is working on a Haskell compiler that will use the clean compiler back end. I can't believe that Clean is so fundamentally different, even with uniqueness types, that it has an edge in compiler optimization. -- View this message in context: http://www.nabble.com/Re%3A--Haskell---Fwd%3A-Re%3A-Computer-Language-Shooto... Sent from the Haskell - Haskell-Cafe mailing list archive at Nabble.com.

Hi
Although there may not be a lot of optimizing Haskell compilers, there are compilers for languages similar to Haskell that consistently perform well. One could point to O'caml or others in the ML family, or even more interesting is the case of Clean, whose syntax heavily borrows from Haskell.
ML is strict, this makes a big difference. Things that Haskell compilers do easily (inlining) are harder in a strict language. Things that strict languages do easily (unboxing) are harder in Haskell. There are enough differences to make it not a "same thing" issue. Clean on the other hand is just Haskell with a different syntax. The Hacle project [1] showed that if you convert Haskell to Clean, you can sometimes beat the performance of Haskell code.
What do the Clean folks do that has made their compiler so consistently competitive? Is it the abc machine? Frankly I'm amazed that a three stack based virtual machine can be translated into such efficient machine code in register centric CPU architecture.
The 3 stacks give a nice computational model of unboxed operations. Maybe this is the thing that allows more effient CPU layout.
Supposedly someone is working on a Haskell compiler that will use the clean compiler back end.
The Clean team are (or were) working on a Haskell front end for Clean. The Yhc team is working on a Clean back end.
I can't believe that Clean is so fundamentally different, even with uniqueness types, that it has an edge in compiler optimization.
Uniqueness types does give some extra optimisation potential, such as destructive updates if you can guarantee a variable is only referred to once. But even with that, the language that has impressed me most on the shootout is Clean. Where the Haskell community spends significant time they can beat Clean, but generally the Clean does very well and looks much more idomatic FP than the Haskell. Thanks Neil [1] google hacle

Uniqueness types does give some extra optimisation potential, such as destructive updates if you can guarantee a variable is only referred to once. But even with that, the language that has impressed me most on the shootout is Clean. Where the Haskell community spends significant time they can beat Clean, but generally the Clean does very well and looks much more idomatic FP than the Haskell.
Clean has strict, unboxed strings by default. We only got these in Haskell in the last few months. -- Don

Hello Neil, Friday, January 26, 2007, 3:06:18 AM, you wrote:
One could point to O'caml or others in the ML family, or even more interesting is the case of Clean, whose syntax heavily borrows from Haskell.
ML is strict, this makes a big difference. Things that Haskell compilers do easily (inlining) are harder in a strict language. Things that strict languages do easily (unboxing) are harder in Haskell. There are enough differences to make it not a "same thing" issue.
actually, Haskell code in shootout is highly optimized and use, among other tricks, `seq` to make all required variables strict and/or unboxed. so the difference only because ML/Clean generates faster code for low-level imperative programs -- Best regards, Bulat mailto:Bulat.Ziganshin@gmail.com
participants (7)
-
apfelmus@quantentunnel.de
-
Bulat Ziganshin
-
dons@cse.unsw.edu.au
-
Kirsten Chevalier
-
Neil Mitchell
-
Philippa Cowderoy
-
SevenThunders