Re: [Haskell-cafe] Data.Binary.encode slower than show
On Sun, Jul 26, 2009 at 10:27:41PM +0200, Grzegorz ChrupaĆa wrote: Hi all, I have a piece of code where I'm serializing a datastructure with the following type [(Int, (Map DType (IntMap Int)))], using Binary.encode The thing is it is very slow: actually quite a bit slower than just using show. This seems rather suspicious. Any idea what could be going on? Does Map serialisation still require flattening the map to a List? Phil -- http://www.kantaka.co.uk/ .oOo. public key: http://www.kantaka.co.uk/gpg.txt ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Help with Bird problem 3.3.3
On Tue, Feb 24, 2009 at 10:25:56AM -0500, Peter Hilal wrote: Where do I go from here? Thank you so much. A hint: I don't think you can do it by recursion on (/). You'll need an auxiliary function. Then prove that your function satisfies the constraint. Phil (Unless there's some clever way to repeatedly divide which comes out with the right answer that I'm not seeing of course...) -- http://www.kantaka.co.uk/ .oOo. public key: http://www.kantaka.co.uk/gpg.txt ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Dynamic typing makes you more productive?
On Tue, Mar 18, 2008 at 09:41:15AM -0700, Justin Bailey wrote: Two years ago I would have agreed with that statement. Now - no way. Make the compiler work for you. I've done a lot of Ruby development and I would never use it for a project of more than 3 or 4 people. It's an awesome language but I don't think it would scale to programming in the large. Any object can be modified at any time. Determining where a particular method comes from can be an exercise in Sherlockian deduction. Give an organization of 100 developers that much freedom and I can only imagine chaos would result. It looks from the outside like Ruby is going through some growing pains as a result of the excerise of too much freedom at the moment. But I wouldn't write Ruby off on account of that: an interesting article I read recently made the comparision with Emacs lisp which offers a similar level of power to the programmer, in that pretty much any function can be redefined at any point, and yet it has a thriving culture of Emacs extensions, all written by disparate people who manage not to step on each other's toes. IOW, it's a cultural issue as well as a language issue. Ruby programmers will no doubt develop their own culture of what is and isn't allowed in publically available extensions just as Emacs lisp programmers have. Phil -- http://www.kantaka.co.uk/ .oOo. public key: http://www.kantaka.co.uk/gpg.txt ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Constructing Data.Map from ByteString
On Mon, Mar 10, 2008 at 11:33:58PM +, Dave Tapley wrote: I've been plugging away at this all day and some discussion in #haskell has been fruitless. Perhaps you have the inspiration to see what's happening! Concerning this minimal example: http://hpaste.org/6268 It works as required, loading K/V pairs into a Data.Map, the concern is the amount of memory used. Pausing (using a getLine) after the readFile one can see (through 'ps v') that the whole file 'f' is loaded in to memory. However once the Map is created the memory footprint swells to around five times the size. Surely this can't be just overhead from Map? My reasoning was that by using ByteString and getting the whole file into memory a small and linear increase would be seen for Map overhead.. Just looking at the code, I'd guess that it's making at least three copies of the data in total, plus Map overhead, so five times larger before garbage collection isn't completely outrageous. (Unless my intuition of what ByteString is doing is completely off-base of course.) Don't forget that Map construction is lazy in its value argument by default: Lots of potential for thunks to hang around the place. I have tried using both Data.ByteString.Char8 and Data.ByteString.Lazy.Char8 with negligible difference. For a hoot I tried it with String and yes, it's ridiculous :) Strings won't help, since you're modifying the data, so you get to pay the string overhead without getting any sharing advantage from the String list implementation. You might do better feeding the input to a proper parser to build the map -- At least then you'd only be copying the input ByteString data once. I don't think you can do much better than that in an immutable world. Phil -- http://www.kantaka.co.uk/ .oOo. public key: http://www.kantaka.co.uk/gpg.txt ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Stack overflow
On Sun, Feb 17, 2008 at 10:01:14PM +, Adrian Hey wrote: Philip Armstrong wrote: Since no-one else has answered, I'll take a stab. Obiously, you have a stack leak due to laziness somewhere I wouldn't say that was obvious, though it is certainly a possibility. I'm never exactly clear what people mean by a stack leak. It seems some folk regard any algorithm that makes use of O(n) or worse stack space as a stack leak. In my personal lexicon, a stack leak is one where you accumulate unevaluated thunks on the stack. In this case, the combination of Data.Map not evaluating it's values and Data.Binary being lazy is (I think) resulting in decode thunks accumulating on the stack. My opinion is that using O(n) or worse working memory when the job could be done in O(log n) or O(1) memory is certainly bad, but using O(n) stack is no worse in principle than using O(n) heap. But at the moment it is worse in practice with ghc, regretably :-( I'd agree with this entirely. In fact, a little experimentation has revealed that this: do [path] - getArgs m - liftM decode (BS.readFile path)::IO [((Int, Maybe String), Int)] putStrLn . show . findMax . fromAscList $ m will work just fine. No extra evaluation needed at all! I'll leave it to the Haskell gurus to explain what's going on... That's very interesting. Strangely if you use fromDistinctAscList instead (as used by the Binary instance get method) the problem re-appears. This is despite fromAscList making use of fromDistinctAscList. Yup. It's because (I've just realised) fromAscList is evaluating the values returned by decode in order to build the Distinct Ascending List to pass to fromDistinctAscList. A previous version I was going to put up simply ran another function over the list before passing it to the map constructor, which was not particularly elegant but also worked. Data.Binary calls fromDistinctAscList to build the map, which is why it gets into this mess. BTW, I find this especially ironic as fromDistinctAscList is the perfect example what I was talking about in another thread (continuation passing madness caused by an irrational fear of stack use). In *some* cases, continuation passing can be quite a bit faster than other approaches IIRC. I haven't looked at this bit of code though. As to what's really going on here, I haven't figured it out and I'm not really inclined to try :-) I did try and do some profiling, but gave up when I realised that I'd have to go sprinking SCCs around the core libraries, which would mean recompiling Data.Map and friends... Heap profile graphs which assign everything to CAF are not very helpful :) Phil -- http://www.kantaka.co.uk/ .oOo. public key: http://www.kantaka.co.uk/gpg.txt LocalWords: fromDistinctAscList IIRC sprinking ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Stack overflow
On Sun, Feb 17, 2008 at 11:45:26PM +, Adrian Hey wrote: But I guess this rant is not much help to the OP :-) Can the Get Monad from Data.Binary be replaced by the one in Data.Binary.Strict.Get? Would probably require some hacking on the library I guess. Phil -- http://www.kantaka.co.uk/ .oOo. public key: http://www.kantaka.co.uk/gpg.txt ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Stack overflow
On Mon, Feb 18, 2008 at 05:56:41PM +, Adrian Hey wrote: Philip Armstrong wrote: On Sun, Feb 17, 2008 at 10:01:14PM +, Adrian Hey wrote: BTW, I find this especially ironic as fromDistinctAscList is the perfect example what I was talking about in another thread (continuation passing madness caused by an irrational fear of stack use). In *some* cases, continuation passing can be quite a bit faster than other approaches IIRC. I haven't looked at this bit of code though. Can you or anyone else give an example? I think I was thinking of this: http://r6.ca/blog/20071028T162529Z.html but can't be entirely sure. Sorry! Phil -- http://www.kantaka.co.uk/ .oOo. public key: http://www.kantaka.co.uk/gpg.txt ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Stack overflow
On Thu, Feb 14, 2008 at 04:56:39AM -0800, Grzegorz Chrupala wrote: I have a very simple program which reads a Data.Map from a file using Data.Binary and Data.ByteString.Lazy, which gives stack overflow with files over a certain size. Any ideas of what might be causing it? You can try it with the small file (11M) at: http://computing.dcu.ie/~gchrupala/map.bin import System import Data.Map import qualified Data.ByteString.Lazy as BS import Data.Binary main = do [path] - getArgs m - fmap decode (BS.readFile path)::IO (Map (Int,Maybe String) Int) putStrLn . show . findMax $ m Since no-one else has answered, I'll take a stab. Obiously, you have a stack leak due to laziness somewhere -- now Data.Map is strict in it's keys, but lazy in it's values, and Data.Binary is lazy so my suspicion would be that you're building up lazy decode thunks for the value elements on the stack as the map is being constructed. If either decode or the Map construction were strict, you'd probably be OK, but the combination is blowing the stack. (Data.Binary serialises Maps by writing them out to a list of key, value pairs in ascending key order. The Map can be reconstructed from this list in O(N) time.) In your specific example, you can replace the type for the result of the decoding with IO [(Int,Maybe String),Int)] and evaluate the right hand sides (with seq if necessary) before constructing the map from the list, which will avoid the stack blowout. In fact, a little experimentation has revealed that this: do [path] - getArgs m - liftM decode (BS.readFile path)::IO [((Int, Maybe String), Int)] putStrLn . show . findMax . fromAscList $ m will work just fine. No extra evaluation needed at all! I'll leave it to the Haskell gurus to explain what's going on... cheers, Phil -- http://www.kantaka.co.uk/ .oOo. public key: http://www.kantaka.co.uk/gpg.txt ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] A handy little consequence of the Cont monad
On Fri, Feb 01, 2008 at 10:19:17PM +, Lennart Augustsson wrote: It's a matter of taste. I prefer the function composition in this case. It reads nicely as a pipeline. (Hoping not to contribute to any flamage...) I've always liked $ for this kind of code, if you want to keep the arguments around: next xs = runCont $ sequence $ map Cont xs seems quite natural to me. Phil -- http://www.kantaka.co.uk/ .oOo. public key: http://www.kantaka.co.uk/gpg.txt ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] The percent operator
On Fri, Nov 16, 2007 at 02:44:33PM +, PR Stanley wrote: I understand 2%4 will construct a fraction in Haskell. I've tried this in GHCI but got an error message. Is there such an operator in Prelude and if so how is it applied? It's not in the Prelude, it's in the Ratio module IIRC. Phil -- http://www.kantaka.co.uk/ .oOo. public key: http://www.kantaka.co.uk/gpg.txt ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Re: Flymake Haskell
On Thu, Nov 15, 2007 at 02:56:32PM +0900, Daisuke IKEGAMI wrote: Dear Stefan and Haskell-Cafe, Thanks to keeping your interest to the flymake-mode for Haskell. Stefan wrote: Could you explain to me what flycheck_haskell.pl does, and give an example of a problematic situation solved by the use of flycheck_haskell.pl. Sure. I'll add in passing that fixing flymake to cope with multi-line errors was fairly simple obviates the need for the extra perl script. I can pass on patches if anyone cares. Phil -- http://www.kantaka.co.uk/ .oOo. public key: http://www.kantaka.co.uk/gpg.txt ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Re: Flymake Haskell
On Thu, Nov 15, 2007 at 09:19:10AM -0500, Denis Bueno wrote: On Nov 15, 2007 7:25 AM, Philip Armstrong [EMAIL PROTECTED] wrote: I can pass on patches if anyone cares. I care! Will dig them out asap then! Phil -- http://www.kantaka.co.uk/ .oOo. public key: http://www.kantaka.co.uk/gpg.txt ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] [OT] GHC uninstall on Linux
On Wed, Nov 07, 2007 at 10:41:53AM +0100, Dusan Kolar wrote: I use tar.bz2 binary distribution of GHC compiler as my distro does not use any supported packaging system. Everything is fine, but... I want to install the new version of the GHC compiler. Is there any (easy) way, how to get information about what was copied and where during installation? (./configure; make install) There seems to be no uninstall target in the Makefile. :-( And I want to uninstall the previous version of the compiler. Is it safe to delete files/folders just from /usr/local/lib/ghc-6.6.1 and /usr/local/bin/gh* ? Probably. At least you installed it in /usr/local, not /usr... For future reference, this is what GNU stow is for: you do $ ./configure --prefix=/usr/local/stow/packagename when you build the binaries and then use the stow command to put appropriate symlinks in to /usr/local/bin, /usr/local/lib etc etc for the version you want to use. This way you can have several versions installed in parallel in /usr/local/stow/ghc-6.6.1 /usr/local/stow/ghc-6.8 etc etc, but have one default version symlinked into your $PATH. Very useful... Phil -- http://www.kantaka.co.uk/ .oOo. public key: http://www.kantaka.co.uk/gpg.txt ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] GHC optimisations
On Mon, Aug 20, 2007 at 09:57:38PM +0100, Simon Peyton-Jones wrote: GHC does some constant folding, but little by way of strength reduction, or using shifts instead of multiplication. It's pretty easy to add more: it's all done in a single module. Look at primOpRules in the module PrelRules. Patches welcome! But please also supply test-suite tests that check the correctness of the rules. Sucking another example out of comp.lang.functional: This: import System f :: Int - Int - Int f s n = if n 0 then f (s+n) (n-1) else s main = do [n] - getArgs putStrLn $ show $ f 0 (read n) is 3-4x slower than this: #include stdio.h #include stdlib.h #include assert.h int f(int s, int n) { return n 0 ? f(s+n, n-1) : s; } int main(int argc, char *argv[]) { assert(argc == 2); printf(%d\n, f(0, strtol(argv[1],0,0))); } The generated assembler suggests (if I've read it correctly) that gcc is spotting that it can replace the tail call with a jump in the C version, but for some reason it can't spot it for the Haskell version when compiling with -fvia-C (and neither does ghc itself using -fasm). So the haskell version ends up pushing and popping values on and off the stack for every call to f, which is a bit sad. Phil -- http://www.kantaka.co.uk/ .oOo. public key: http://www.kantaka.co.uk/gpg.txt ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] GHC optimisations
On Tue, Aug 21, 2007 at 05:25:49AM -0700, Stefan O'Rear wrote: On Tue, Aug 21, 2007 at 01:14:20PM +0100, Rodrigo Queiro wrote: On my system, the C version runs about 9x faster than the haskell version (with -O3 and -O2 -fvia-c -optc-O3 respectively). However, GCC seems to produce about 70 lines of assembly for the main loop, compared to about 10 from GHC. I suspect the speed difference is the result of some heavy optimisation by GCC, which would need to be hand-tuned for GHC. (I would be interested to see what this would be. Unfortunately I don't know x86 assembly well enough to understand the GCC output.) GCC is carrying out two major optimisations that ghc is missing here: replacing the tail call with a jump directly into the function body (having stuffed the correct arguments into the appropriate registers) and unrolling the loop. That's pretty much it. Neither are what I'd call 'heavy' optimisations. The fundamental problem is that GHC doesn't have enough registers to to a good job with Haskell. Normal Haskell code makes extensive use of the GHC stack for function calls, the C stack for signal handlers, the capability base pointer for thread state, and the heap for everything else. Which doesn't really leave us in a good state for optimizing. In particular, x86 ghc ALWAYS passes parameters on the stack, even for tail calls. I didn't actually bother to check, but I'm pretty sure that's what the OP was noticing - if you look carefully it's not actually pushing or popping anything, just using stack memory. Yes, absolutely. Situations are far better on x86_64 (16 registers) and ppc (32 registers). There is some work being done on the backend to improve this (in particular, a new and much better register allocator and a parameter-aware Cmm system). fires up ppc box Ouch. That's even worse: $ ./sum 1 C version: 0.16s Haskell : 1.40s Looking at the generated assembler, the ppc version has exactly the same problem that the x86 version does. It carries out the calculation, the stores the result in some memory locations and calls f again so that the preamble to f can pull those same results out of the memory locations in order to put them back into the same registers again! (I'm using ghc 6.6.1 on Debian unstable btw for anyone following along.) cheers, Phil -- http://www.kantaka.co.uk/ .oOo. public key: http://www.kantaka.co.uk/gpg.txt ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] GHC optimisations
Don's reply didn't reach me for some reason, but pulling it out of the previous response: On 21/08/07, Donald Bruce Stewart [EMAIL PROTECTED] wrote: phil: The generated assembler suggests (if I've read it correctly) that gcc is spotting that it can replace the tail call with a jump in the C version, but for some reason it can't spot it for the Haskell version when compiling with -fvia-C (and neither does ghc itself using -fasm). So the haskell version ends up pushing and popping values on and off the stack for every call to f, which is a bit sad. That doesn't sound quite right. The C version should get a tail call , with gcc -O2, the Haskell version should be a tail call anyway. Just to be clear; the Haskell version is a tail call, but it's pushing the values to and from memory (well, cache really of course) for every call to f, which is killing the performance. Let's see: C $ gcc -O t.c -o t $ time ./t 10 zsh: segmentation fault (core dumped) ./t 10 ./t 10 0.02s user 0.22s system 5% cpu 4.640 total Turning on -O2 $ time ./t 10 -243309312 ./t 10 1.89s user 0.00s system 97% cpu 1.940 total -O3 does better thanks to the loop unrolling, see timings bellow. And GHC: $ ghc -O2 A.hs -o A $ time ./A 10 -243309312 ./A 10 3.21s user 0.01s system 97% cpu 3.289 total So, what, 1.6x slower than gcc -O2 Seems ok without any tuning. You're getting much better timings than I am! $ time -p ./sum-hs 10 -243309312 real 3.75 user 3.70 $ time -p ./sum-c-O2 10 -243309312 real 1.40 user 1.35 $ time -p ./sum-c-O3 10 -243309312 real 1.21 user 1.18 (My box has a AMD Athlon64 3000+ CPU fwiw, but the powerpc version is even worse when compared to it's respective C binary!) Phil -- http://www.kantaka.co.uk/ .oOo. public key: http://www.kantaka.co.uk/gpg.txt ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Weird ghci behaviour?
On Mon, Jul 23, 2007 at 11:46:41AM -0700, Dan Piponi wrote: Ian said: Can you please give a complete testcase for the problem you're seeing? I took my test case and started deleting lines from it to simplify it. And now I'm not seeing the problem at all and I can't reproduce it, even though when I originally posted I was getting it repeatably. I'm either hallucinating or it's a problem that comes up intermittently. Maybe it's some kind of network time skew issue that has nothing to do with ghc. If I catch it happening again I'll make sure to do more investigation. GHC 6.6 had some kind of memory allocation bug that led to all kind of weird errors in GHCi. Maybe try 6.6.1 ? Phil -- http://www.kantaka.co.uk/ .oOo. public key: http://www.kantaka.co.uk/gpg.txt ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Very freaky
On Thu, Jul 12, 2007 at 10:11:07PM +0100, Andrew Coppin wrote: Felipe Almeida Lessa wrote: On 7/12/07, Andrew Coppin [EMAIL PROTECTED] wrote: How come the set of all sets doesn't exist? http://www.google.com/search?q=set+of+all+sets leads to http://en.wikipedia.org/wiki/Set_of_all_sets which has the answer, I think. Ouch. Clearly, set theory is way more complicated than people make out. (I always thought a set was just a collection of objects...) If a set is just a *finite* collection of objects, then things are usually fairly straightforward. It's those pesky infinite sets that complicate things...especially the ones which aren't constructible. Phil -- http://www.kantaka.co.uk/ .oOo. public key: http://www.kantaka.co.uk/gpg.txt ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Type system madness
On Thu, Jul 12, 2007 at 07:01:31PM +0100, Andrew Coppin wrote: Let me put it this way: It makes all my Tcl scripts stop working, and it makes my Haskell-based processor go nuts too... Given that (IIRC) the BOM is just a valid unicode non-breaking space, your scripts really ought to cope... Phil -- http://www.kantaka.co.uk/ .oOo. public key: http://www.kantaka.co.uk/gpg.txt ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Type system madness
On Thu, Jul 12, 2007 at 09:24:24PM +0100, Philip Armstrong wrote: On Thu, Jul 12, 2007 at 07:01:31PM +0100, Andrew Coppin wrote: Let me put it this way: It makes all my Tcl scripts stop working, and it makes my Haskell-based processor go nuts too... Given that (IIRC) the BOM is just a valid unicode non-breaking space, your scripts really ought to cope... Oh wait, is the problem that the scripts are expecting ascii, and are breaking on the non-breaking space? That makes a certain amount of (annoying) sense. Phil -- http://www.kantaka.co.uk/ .oOo. public key: http://www.kantaka.co.uk/gpg.txt ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] function unique
On Wed, Jul 11, 2007 at 10:31:36PM +0200, Hugh Perkins wrote: Ok so I played with the tweaked problem (Unix 'uniq'), and getting it to be lazy. This seems to work: It's slightly worse than that: unix uniq only eliminates *consecutive* identical lines from its input. If you want to eliminate all duplicates, you have to pipe your input through sort first. testunique :: Eq a = [a] - [a] testunique list = testunique' list [] where testunique' :: Eq a = [a] - [a] - [a] testunique' [] elementssofar = [] testunique' (x:xs) elementssofar | x `elem` elementssofar = (testunique' elementssofar xs) | otherwise = x : ( testunique' xs (x:elementssofar)) I suspect the author upthread had something more like this in mind: uniq :: Eq a = [a] - [a] uniq [] = [] uniq (x:xs) = x : filter (x/=) (uniq2 xs) Obviously a true 'unique' function has to traverse the entire list before it creates any output, as has been pointed out upthread. Phil -- http://www.kantaka.co.uk/ .oOo. public key: http://www.kantaka.co.uk/gpg.txt ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Type system madness
On Thu, Jul 12, 2007 at 04:58:43PM -0400, Steve Schafer wrote: On Thu, 12 Jul 2007 21:24:24 +0100, you wrote: Given that (IIRC) the BOM is just a valid unicode non-breaking space, your scripts really ought to cope... Choking on the BOM is probably just a symptom of a deeper problem. My bet is that removing the BOM would simply delay the failure until the first non-ASCII character was encountered. Indeed. However, I can imagine that the author might well want to use unicode characters in string literals and comments, where they would be entirely inocuous (since a utf-8 string is a valid ascii string) but the BOM at the beginning of the file breaks things. Phil -- http://www.kantaka.co.uk/ .oOo. public key: http://www.kantaka.co.uk/gpg.txt ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] More binary IO, compression, bytestrings and FFI fun
On Mon, Jul 09, 2007 at 02:42:49PM +1000, Donald Bruce Stewart wrote: Processing larger amounts of data, compression, serialisation and calling C. Just a thought: is it worth sticking this up on the wiki? Phil -- http://www.kantaka.co.uk/ .oOo. public key: http://www.kantaka.co.uk/gpg.txt ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Re: Too many packages on hackage? :-)
On Mon, Jul 09, 2007 at 06:05:44PM +0200, Marc Weber wrote: Another idea I've been pondering is allowing people to add links to documentation for libraries, from their hackage page. We have a fair few libs documented in blog form, here, Beeing able adding some comments (wiki style) would be cool. This way we could add comments such like: Have a look at ... which does the same thing but better. Unmaintaned etc.. CPAN has something much like this, plus user ratings which together with the comment system help sort through the endless perl extensions. Phil -- http://www.kantaka.co.uk/ .oOo. public key: http://www.kantaka.co.uk/gpg.txt ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] More binary IO, compression, bytestrings and FFI fun
On Mon, Jul 09, 2007 at 06:53:15PM +1000, Donald Bruce Stewart wrote: phil: On Mon, Jul 09, 2007 at 02:42:49PM +1000, Donald Bruce Stewart wrote: Processing larger amounts of data, compression, serialisation and calling C. Just a thought: is it worth sticking this up on the wiki? http://haskell.org/haskellwiki/Serialisation_and_compression_with_Data_Binary :-) I should have had more faith :) Phil -- http://www.kantaka.co.uk/ .oOo. public key: http://www.kantaka.co.uk/gpg.txt ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Binary serialization, was Re: Abstraction leak
On Thu, Jul 05, 2007 at 08:50:42AM +1000, Donald Bruce Stewart wrote: [useful stuff] So, in fact pretty much everything I was looking for exists, in some form or other! It's just a bit hard to find at the moment, perhaps because none of this stuff is regarded as 'core Haskell' by any of the tutorials, books etc etc. I'll have a play with some of the libraries mentioned upthread anyway. Thanks everyone. Phil -- http://www.kantaka.co.uk/ .oOo. public key: http://www.kantaka.co.uk/gpg.txt ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Binary serialization, was Re: Abstraction leak
On Thu, Jul 05, 2007 at 09:41:23AM -0700, Dave Bayer wrote: There are people who claim with a straight face that they migrated to OS X primarily to use TextMate http://www.textmate.com Presumably you mean http://macromates.com/ ? Phil -- http://www.kantaka.co.uk/ .oOo. public key: http://www.kantaka.co.uk/gpg.txt ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Re: Abstraction leak
On Sun, Jul 01, 2007 at 06:07:13PM +0100, Andrew Coppin wrote: I haven't actually tried, but presumably a TCP connection is represented in the same way as a file, and so has the same problems. Basically doing binary I/O seems to be one of those things that in Haskell falls into the class of it's possibly but annoyingly messy... In an ideal world there would be a 'deriving Serializable[1]' you could do on datatypes which would get this right. In a really ideal world, you could specify the data layout somehow[2][2a], which would make integrating Haskell code into a wider distributed network of processes exchanging binary data a cinch. In a super really ideal world, you could operate on the packets in place in Haskell where possible and save the deserialization overhead... Anyone trying to do any of this? Phil [1] deriving picklable? [2] DFDL does this for XML / binary data translation. [2a] Or even dump to arbitrary formats: XML, JSON for concrete datatypes[3], mabe use the approach from http://www.ps.uni-sb.de/Papers/abstracts/hotPickles2007.html (link stolen shamelessly from Lambda the Ultimate) for higher order data? [3] Maybe UBL from http://www.erlang.se/workshop/2002/Armstrong.pdf ? -- http://www.kantaka.co.uk/ .oOo. public key: http://www.kantaka.co.uk/gpg.txt ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Re: Abstraction leak
On Wed, Jul 04, 2007 at 09:02:15PM +1000, Donald Bruce Stewart wrote: phil: On Sun, Jul 01, 2007 at 06:07:13PM +0100, Andrew Coppin wrote: I haven't actually tried, but presumably a TCP connection is represented in the same way as a file, and so has the same problems. Basically doing binary I/O seems to be one of those things that in Haskell falls into the class of it's possibly but annoyingly messy... In an ideal world there would be a 'deriving Serializable[1]' you derive Binary (use an external tool for this) such as? could do on datatypes which would get this right. In a really ideal world, you could specify the data layout somehow[2][2a], which would Directly in Haskell data type decls -- see the ICFP 05 paper on the House OS, which added packing annotations, and bit syntax. In current Haskell, you specify the layout in instances Storable or Binary. I'll have a look. make integrating Haskell code into a wider distributed network of processes exchanging binary data a cinch. In a super really ideal Definitely. See things like the zlib or iconv Data.Binary/Data.ByteString bindings, for prototypes. The 'tar' reader/writer on hackage.haskell.org is also a good example. OK. Maybe this is the sort of stuff which ought to go into the new Haskell book? 'Integrating Haskell with external data sources' or something... world, you could operate on the packets in place in Haskell where possible and save the deserialization overhead... Data.ByteString.* for this. Anyone trying to do any of this? Yeah, its a bit of a hot topic currently. :) Gotta chase Erlang for hacking network data. Absolutely. Ta for the pointers anyway. Phil -- http://www.kantaka.co.uk/ .oOo. public key: http://www.kantaka.co.uk/gpg.txt ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Binary serialization, was Re: Abstraction leak
On Wed, Jul 04, 2007 at 09:44:13PM +1000, Donald Bruce Stewart wrote: Binary instances are pretty easy to write. For a simple data type: instance Binary Exp where put (IntE i) = do put (0 :: Word8) put i put (OpE s e1 e2) = do put (1 :: Word8) put s put e1 put e2 get = do tag - getWord8 case tag of 0 - liftM IntE get 1 - liftM3 OpE get get get That's quite verbose! Plus I'm a bit concerned by the boxing implied by those IntE / OpE constructors in get. If you were using those values in a pattern match on the result of get, would the compiler be able to eliminate them and refer directly to the values in the source data? The Data.Binary comes with one tool to derive these. The DrIFT preprocessor also can, as can Stefan O'Rear's SYB deriver. I just write them by hand, or use the tool that comes with the lib. More docs here, http://hackage.haskell.org/packages/archive/binary/0.3/doc/html/Data-Binary.html This doesn't seem to deal with endianness. Am I missing something? world, you could operate on the packets in place in Haskell where possible and save the deserialization overhead... Data.ByteString.* for this. Ah, does Data.Binary fuse with ByteString.* then? Hack those bytes! Quickly! :-) :) It's a shame the layout definition is so verbose. Erlang's is quite compact. I wonder if something could be done with template haskell to translate an Erlang-style data layout definition to the Data.Binary form? (Bonus points for being able to parse ASN.1 and generate appropriate Haskell datatypes serialization primitives automatically :-) ) Phil -- http://www.kantaka.co.uk/ .oOo. public key: http://www.kantaka.co.uk/gpg.txt ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Binary serialization, was Re: Abstraction leak
On Wed, Jul 04, 2007 at 06:52:08PM +0400, Bulat Ziganshin wrote: Hello Philip, Wednesday, July 4, 2007, 5:50:42 PM, you wrote: This doesn't seem to deal with endianness. Am I missing something? alternative: http://haskell.org/haskellwiki/Library/AltBinary http://haskell.org/haskellwiki/Library/Streams Nice: bit aligning if you want it, little or big endian IO. Intermixed endianness in the same datastream even[1]. However: 3.2.10 Defining Binary instances for custom serialization formats (unwritten) Does that mean that the code is unwritten or that the documentation is unwritten. IAMFI :) There seems to be some overlap between Streams and ByteStrings: Could a Stream built on a ByteString backend benefit from all the fusion work that's been put into ByteStrings recently? Oh wait, I see you list that as 'future work' on the wiki page... Phil [1] Which sick application *needs* intermixed endianness? -- http://www.kantaka.co.uk/ .oOo. public key: http://www.kantaka.co.uk/gpg.txt ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Binary serialization, was Re: Abstraction leak
On Wed, Jul 04, 2007 at 09:15:59PM +0400, Bulat Ziganshin wrote: Does that mean that the code is unwritten or that the documentation is unwritten. IAMFI :) of course all unwritten notes means unfinished docs. library contains more than 100 functions so it was not easy to document them all. you can browse sources, although probably it will not help too much OK. There seems to be some overlap between Streams and ByteStrings: Could a Stream built on a ByteString backend benefit from all the fusion work that's been put into ByteStrings recently? Oh wait, I see you list that as 'future work' on the wiki page... if you will write all popular words together, this probably will be just a set of popular words, not something working :) how fusion should work together with serialization? I'm thinking of the elimination of the boxing of values drawn out of the input stream where possible, eg if I was writing a stream processor that folded across the values in the input stream, it would (presumably) be more efficient if the compiler noticed that the function in question was (say) just reading Int values at offsets within the stream, and could pass those as unboxed references in the compiled code rather than freshly constructed values. Fusion might be the wrong term: I was thinking by analogy with loop fusion, with one of the loops was the 'data reading' loop. Does that make sense? [1] Which sick application *needs* intermixed endianness? i just tried to implement everything possible :) Completeness is always good! Thanks for the pointers, Phil -- http://www.kantaka.co.uk/ .oOo. public key: http://www.kantaka.co.uk/gpg.txt ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Binary serialization, was Re: Abstraction leak
On Wed, Jul 04, 2007 at 07:36:11PM +0100, Andrew Coppin wrote: Philip Armstrong wrote: [1] Which sick application *needs* intermixed endianness? *Clearly* you've never been to Singapore... ...er, I mean, Ever tried playing with networking protocol stacks? No (thankfully?). Phil -- http://www.kantaka.co.uk/ .oOo. public key: http://www.kantaka.co.uk/gpg.txt ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: Re[2]: [Haskell-cafe] XmlSerializer.deserialize?
On Mon, Jul 02, 2007 at 12:23:36AM +0200, Hugh Perkins wrote: Clll :-) Thanks for the link. Er are you the Philip Armstrong I was at college with Shhh. Don't tell everyone or they'll all want one. (iow, yes: Probably.) Phil -- http://www.kantaka.co.uk/ .oOo. public key: http://www.kantaka.co.uk/gpg.txt ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: Re[2]: [Haskell-cafe] XmlSerializer.deserialize?
On Sun, Jul 01, 2007 at 10:48:11PM +0200, Hugh Perkins wrote: On 7/1/07, Bulat Ziganshin [EMAIL PROTECTED] wrote: btw, are you read Hoar's book Communicating Sequential Processes? i think that his model is very FPish and reading his book should allow to switch your look at concurrency in right direction No, I'll check it out. Just as a point of interest, Jim Davies at Oxford University Computing Lab. has edited a revised edition of Tony Hoare's book which is freely available from http://usingcsp.com/. (Full disclosure: my day job is/was developing CSP-related tools.) Phil -- http://www.kantaka.co.uk/ .oOo. public key: http://www.kantaka.co.uk/gpg.txt ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Haskell version of ray tracer code is much slowerthan the original ML
On Sat, Jun 23, 2007 at 12:42:33AM +0100, Claus Reinke wrote: http://www.kantaka.co.uk/darcs/ray try making ray_sphere and intersect' local to intersect, then drop their constant ray parameter. saves me 25%. claus I see: I guess I'm paying for laziness in the first parameter to intersect' which I don't need. 25% brings it within spitting distance of the OCaml binary too. Phil -- http://www.kantaka.co.uk/ .oOo. public key: http://www.kantaka.co.uk/gpg.txt ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Haskell version of ray tracer code is much slower than the original ML
On Sat, Jun 23, 2007 at 08:49:15AM +0100, Andrew Coppin wrote: Donald Bruce Stewart wrote: Don't use -O3 , its *worse* than -O2, and somewhere between -Onot and -O iirc, Is this likely to be fixed ever? There is at least a bug report for it IIRC. Phil -- http://www.kantaka.co.uk/ .oOo. public key: http://www.kantaka.co.uk/gpg.txt ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Haskell version of ray tracer code is much slower than the original ML
On Sat, Jun 23, 2007 at 03:28:53AM +0100, Jon Harrop wrote: What architecture, platform, compiler versions and compile lines are you using? 32-bit x86, Debian unstable, gcc version 4.1.2, OCaml version 3.09.2-9, GHC version 6.6.1, compile line in the Makfile at http://www.kantaka.co.uk/darcs/ray/Makefile http://www.ffconsultancy.com/languages/ray_tracer/code/5/ray.ml http://www.ffconsultancy.com/languages/ray_tracer/code/5/ray.cpp I gather these use algorithmic optimisations. cheers, Phil -- http://www.kantaka.co.uk/ .oOo. public key: http://www.kantaka.co.uk/gpg.txt ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Haskell version of ray tracer code is muchslowerthan the original ML
On Sat, Jun 23, 2007 at 12:05:01PM +0100, Claus Reinke wrote: http://www.kantaka.co.uk/darcs/ray try making ray_sphere and intersect' local to intersect, then drop their constant ray parameter. saves me 25%. claus also try replacing that (foldl' intersect') with (foldr (flip intersect'))! Thanks guys, this is exactly the kind of advice I was seeking. OK, next question: Given that I'm using all the results from intersect', why is the lazy version better than the strict one? Is ghc managing to do some loop fusion? using a recent ghc head instead of ghc-6.6.1 also seems to make a drastic difference (wild guess, seeing the unroll 1000 for ocaml: has there been a change to default unrolling in ghc?). Um. I tried ghc head on the current version and it was about 15% *slower* than 6.6.1 Perhaps it does better on the (slightly) optimised version? Phil -- http://www.kantaka.co.uk/ .oOo. public key: http://www.kantaka.co.uk/gpg.txt ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Haskell version of ray tracer code is muchslowerthan the original ML
On Sat, Jun 23, 2007 at 07:07:49PM +0100, Philip Armstrong wrote: On Sat, Jun 23, 2007 at 12:05:01PM +0100, Claus Reinke wrote: http://www.kantaka.co.uk/darcs/ray try making ray_sphere and intersect' local to intersect, then drop their constant ray parameter. saves me 25%. claus also try replacing that (foldl' intersect') with (foldr (flip intersect'))! Thanks guys, this is exactly the kind of advice I was seeking. OK, next question: Given that I'm using all the results from intersect', why is the lazy version better than the strict one? Is ghc managing to do some loop fusion? Incidentally, replacing foldl' (intersect ray) hit scene with foldr (flip (intersect ray)) hit scene makes the current version (without the lifting of ray out of intersect ray_scene) almost exactly as fast as the OCaml version on my hardware. That's almost a 40% speedup! using a recent ghc head instead of ghc-6.6.1 also seems to make a drastic difference (wild guess, seeing the unroll 1000 for ocaml: has there been a change to default unrolling in ghc?). Um. I tried ghc head on the current version and it was about 15% *slower* than 6.6.1 Perhaps it does better on the (slightly) optimised version? Nope, just tried it on the foldr version. It's still slower than 6.6.1 (although not by as much: 26s vs 24s for the 6.6.1 binary). This is ghc head from this Friday. Jon is probably correct that hoisting ray out is a code level transformation that makes the Haskell version different to the OCaml one, but personally I'd suggest that replacing foldl with foldr is not: the end result is the same both have to walk the entire list in order to get a result. So, on my hardware at least, the Haskell and OCaml version have equivalent performance. I think that's pretty impressive. Getting close to the C++ would probably going to require rather more effort! Phil -- http://www.kantaka.co.uk/ .oOo. public key: http://www.kantaka.co.uk/gpg.txt ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Haskell version of ray tracer code is much slower than the original ML
On Sat, Jun 23, 2007 at 10:32:31AM +0100, Jon Harrop wrote: On Saturday 23 June 2007 08:58:10 Philip Armstrong wrote: On Sat, Jun 23, 2007 at 03:28:53AM +0100, Jon Harrop wrote: What architecture, platform, compiler versions and compile lines are you using? 32-bit x86... Intel or AMD? AMD. Athlon 64 3000+ to be precise. http://www.ffconsultancy.com/languages/ray_tracer/code/5/ray.ml http://www.ffconsultancy.com/languages/ray_tracer/code/5/ray.cpp I gather these use algorithmic optimisations. Both. Versions 1-4 are progressively algorithmic, version 5 includes low-level optimizations (mostly manual inlining and unrolling). Implementing version 1 is probably also interesting: it is the most concise version. BTW, the ray tracer leverages the semantics of the float infinity (as the parameter when there is no intersection). Shouldn't be a problem but some compiler options might break it. Thus far the Haskell version generates identical images to the OCaml one. Phil -- http://www.kantaka.co.uk/ .oOo. public key: http://www.kantaka.co.uk/gpg.txt ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Haskell version of ray tracer code is much slower than the original ML
On Thu, Jun 21, 2007 at 08:42:57PM +0100, Philip Armstrong wrote: On Thu, Jun 21, 2007 at 03:29:17PM -0400, Mark T.B. Carroll wrote: Philip Armstrong [EMAIL PROTECTED] writes: (snip) Why on earth would you use -fexcess-precision if you're using Floats? The excess precision only apples to Doubles held in registers on x86 IIRC. (If you spill a Double from a register to memory, then you lose the extra precision bits in the process). Some googling suggests that point 2 on http://www.haskell.org/hawiki/FasterFloatingPointWithGhc might have been what I was thinking of. That's the old wiki. The new one gives the opposite advice! (As does the ghc manual): http://www.haskell.org/ghc/docs/latest/html/users_guide/faster.html http://www.haskell.org/haskellwiki/Performance/Floating_Point Incidentally, the latter page implies that ghc is being overly pessimistic when compilling FP code without -fexcess-precision: On x86 (and other platforms with GHC prior to version 6.4.2), use the -fexcess-precision flag to improve performance of floating-point intensive code (up to 2x speedups have been seen). This will keep more intermediates in registers instead of memory, at the expense of occasional differences in results due to unpredictable rounding. IIRC, it is possible to issue an instruction to the x86 FP unit which makes all operations work on 64-bit Doubles, even though there are 80-bits available internally. Which then means there's no requirement to spill intermediate results to memory in order to get the rounding correct. Ideally, -fexcess-precision should just affect whether the FP unit uses 80 or 64 bit Doubles. It shouldn't make any performance difference, although obviously the generated results may be different. As an aside, if you use the -optc-mfpmath=sse option, then you only get 64-bit Doubles anyway (on x86). cheers, Phil -- http://www.kantaka.co.uk/ .oOo. public key: http://www.kantaka.co.uk/gpg.txt ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Re: Haskell version of ray tracer code is much slower than the original ML
On Fri, Jun 22, 2007 at 01:16:54PM +0100, Simon Marlow wrote: Philip Armstrong wrote: IIRC, it is possible to issue an instruction to the x86 FP unit which makes all operations work on 64-bit Doubles, even though there are 80-bits available internally. Which then means there's no requirement to spill intermediate results to memory in order to get the rounding correct. For some background on why GHC doesn't do this, see the comment MORE FLOATING POINT MUSINGS... in http://darcs.haskell.org/ghc/compiler/nativeGen/MachInstrs.hs Twisty. I guess 'slow, but correct, with switches to go faster at the price of correctness' is about the best option. You probably want SSE2. If I ever get around to finishing it, the GHC native code generator will be able to generate SSE2 code on x86 someday, like it currently does for x86-64. For now, to get good FP performance on x86, you probably want -fvia-C -fexcess-precision -optc-mfpmath=sse2 Reading the gcc manpage, I think you mean -optc-msse2 -optc-mfpmath=sse. -mfpmath=sse2 doesn't appear to be an option. (I note in passing that the ghc darcs head produces binaries from ray.hs which are about 15% slower than ghc 6.6.1 ones btw. Same optimisation options used both times.) cheers, Phil -- http://www.kantaka.co.uk/ .oOo. public key: http://www.kantaka.co.uk/gpg.txt ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] A probably-stupid question about a Prelude implementation.
On Fri, Jun 22, 2007 at 11:31:17PM +0800, Michael T. Richter wrote: 1. Using foldr means I'll be traversing the whole list no matter what. This implies (perhaps for a good reason) that it can only work on a finite list. foldr is lazy. Please tell me I'm wrong and that I'm missing something? You are wrong and you're missing something :) compare: any ((==) 2) [1,2,3] and any ((==) 2) [1..] any ((==) 0) [1..] will go _|_ of course. Phil -- http://www.kantaka.co.uk/ .oOo. public key: http://www.kantaka.co.uk/gpg.txt ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Haskell version of ray tracer code is much slower than the original ML
On Thu, Jun 21, 2007 at 01:45:04PM +0100, Philip Armstrong wrote: As I said, I've tried the obvious things they didn't make any difference. Now I could go sprinkling $!, ! and seq around like confetti but that seems like giving up really. OK. Looks like I was mistaken. Strictness annotations *do* make a difference! Humph. Wonder what I was doing wrong yesterday? Anyway timings follow, with all strict datatypes in the Haskell version: Langauge File Time in seconds Haskell ray.hs 38.2 OCamlray.ml 23.8 g++-4.1 ray.cpp 12.6 (ML C++ Code from http://www.ffconsultancy.com/languages/ray_tracer/comparison.html) Gcc seems to have got quite a bit better since Jon last benchmarked this code. Phil -- http://www.kantaka.co.uk/ .oOo. public key: http://www.kantaka.co.uk/gpg.txt ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Haskell version of ray tracer code is much slower than the original ML
On Fri, Jun 22, 2007 at 10:11:27PM +0400, Bulat Ziganshin wrote: Friday, June 22, 2007, 7:36:51 PM, you wrote: Langauge File Time in seconds Haskell ray.hs 38.2 OCamlray.ml 23.8 g++-4.1 ray.cpp 12.6 can you share sourcecode of this variant? i'm interested to see how much it is obfuscated http://www.kantaka.co.uk/darcs/ray The cpp ml versions are precisely those available from the download links on http://www.ffconsultancy.com/languages/ray_tracer/comparison.html The optimisation options I used can be seen in the makefile. btw, *their* measurement said that ocaml is 7% faster :) Indeed. The gcc-4.0 compilied binary runs at about 15s IIRC, but it's still much better than 7% faster than the ocaml binary. cheers, Phil -- http://www.kantaka.co.uk/ .oOo. public key: http://www.kantaka.co.uk/gpg.txt ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Haskell version of ray tracer code is much slower than the original ML
In odd spare moments, I took John Harrops simple ray tracer[1] made a Haskell version: http://www.kantaka.co.uk/cgi-bin/darcsweb.cgi?r=ray darcs get http://www.kantaka.co.uk/darcs/ray It's pretty much a straight translation into idiomatic Haskell (as far as my Haskell is idiomatic anyway). Unfortunately, it's a lot slower than the ML version, despite turning all the optimisation options up as far as they'll go. Profiling suggests that much of the time is spent in the intersection' function, and that the code is creating (and garbage collecting) an awful lot of (-|) vector subtraction thunks. Trying to make intersection' or ray_sphere stricter (with seq) appears to have no effect whatsoever: the output of -ddump-simpl is unchanged (with the arguments all staying lazy). Am I missing anything obvious? I don't want to carry out herculean code rewriting efforts: that wouldn't really be in the spirit of the thing. cheers, Phil [1] http://www.ffconsultancy.com/languages/ray_tracer/comparison.html -- http://www.kantaka.co.uk/ .oOo. public key: http://www.kantaka.co.uk/gpg.txt ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Haskell version of ray tracer code is much slower than the original ML
On Thu, Jun 21, 2007 at 12:25:44PM +0100, Sebastian Sylvan wrote: Try using floats for the vector, and strict fields (add a ! to the fields in the data declaration). Because the optimisation page on the haskell wiki is very explicit about never using Float when you can use Double, that's why. An older revision used Float and it was slower than the current one. Making the datatypes strict also makes no difference. I have tried the obvious things :) That's the simplest possible thing I can think of after about two seconds of looking anyway. It appears that the ML version uses float so I don't understand why you would use Double for the Haskell version at all, and then think you could do any sort of valid comparisons between them... OCaML floats are Doubles, at least on x86. cheers, Phil -- http://www.kantaka.co.uk/ .oOo. public key: http://www.kantaka.co.uk/gpg.txt ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Haskell version of ray tracer code is much slower than the original ML
On Thu, Jun 21, 2007 at 04:23:37PM +0400, Bulat Ziganshin wrote: Thursday, June 21, 2007, 3:36:27 PM, you wrote: revision used Float and it was slower than the current one. Making the datatypes strict also makes no difference. don't forget to use either -funpack-strict-fields or {#- UNPACK -#} pragma ahem: http://www.kantaka.co.uk/cgi-bin/darcsweb.cgi?r=ray;a=headblob;f=/Makefile (Assuming you mean -funbox-strict-fields; -funpack-strict-fields doesn't appear in the ghc 6.6.1 makefile as far as I can see.) As I said, I've tried the obvious things they didn't make any difference. Now I could go sprinkling $!, ! and seq around like confetti but that seems like giving up really. Phil -- http://www.kantaka.co.uk/ .oOo. public key: http://www.kantaka.co.uk/gpg.txt ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Haskell version of ray tracer code is much slower than the original ML
On Thu, Jun 21, 2007 at 01:39:24PM +0100, Jon Harrop wrote: Awesome stuff! On Thursday 21 June 2007 12:36:27 Philip Armstrong wrote: On Thu, Jun 21, 2007 at 12:25:44PM +0100, Sebastian Sylvan wrote: Try using floats for the vector, and strict fields (add a ! to the fields in the data declaration). Because the optimisation page on the haskell wiki is very explicit about never using Float when you can use Double, that's why. An older revision used Float and it was slower than the current one. Making the datatypes strict also makes no difference. Where exactly do the !s go and what do they do? On the datatypes: data Vector = V !Double !Double !Double for instance. They tell the compiler to make those fields strict rather than lazy. This may or may not help things... OCaML floats are Doubles, at least on x86. Yes. OCaml doesn't have a 32-bit float storage format, apart from an entirely-float big array. Also, the ML in OCaml doesn't stand for metalanguage. ;-) Point! I take it you saw the whole language comparison: http://www.ffconsultancy.com/languages/ray_tracer/ Yup. I'd been meaning to run off a haskell version for a while. I'll be uploading concurrent implementations ASAP. Haskell should do well there... :-) I'll be on the lookout. PS: You spelled my name wrong! Sorry! Phil -- http://www.kantaka.co.uk/ .oOo. public key: http://www.kantaka.co.uk/gpg.txt ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Haskell version of ray tracer code is much slower than the original ML
On Thu, Jun 21, 2007 at 01:29:56PM -0400, Mark T.B. Carroll wrote: Philip Armstrong [EMAIL PROTECTED] writes: (snip) Because the optimisation page on the haskell wiki is very explicit about never using Float when you can use Double, that's why. (snip) Is that still true if you use -fexcess-precision ? Why on earth would you use -fexcess-precision if you're using Floats? The excess precision only apples to Doubles held in registers on x86 IIRC. (If you spill a Double from a register to memory, then you lose the extra precision bits in the process). Unless -fexcess-precision with ghc does something completely different to the analogous gcc setting that is. Phil -- http://www.kantaka.co.uk/ .oOo. public key: http://www.kantaka.co.uk/gpg.txt ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Haskell version of ray tracer code is much slower than the original ML
On Thu, Jun 21, 2007 at 08:15:36PM +0200, peterv wrote: So float math in *slower* than double math in Haskell? That is interesting. Why is that? BTW, does Haskell support 80-bit long doubles? The Intel CPU seems to use that format internally. As I understand things, that is the effect of using -fexcess-precision. Obviously this means that the behaviour of your program can change with seemingly trivial code rearrangements, but if you're messing with floating point numbers then you ought to know what you're doing anyway. Phil -- http://www.kantaka.co.uk/ .oOo. public key: http://www.kantaka.co.uk/gpg.txt ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe