Re: [Haskell-cafe] qsort

2009-08-16 Thread Gwern Branwen
On Sat, Aug 15, 2009 at 12:09 PM, Daniel
Fischerdaniel.is.fisc...@web.de wrote:
 It compiles as is, and if it satisfies readability requirements, somebody can 
 put it on
 the wiki.


http://www.haskell.org/haskellwiki/?title=Introduction%2FDirect_Translationdiff=29575oldid=21061

I've done so; it'd be nice if you could add some usage examples and
timings (especially of the 80x performance of the original).

-- 
gwern
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] qsort

2009-08-15 Thread Daniel Fischer
Am Samstag 15 August 2009 10:09:28 schrieb Peter Verswyvelen:
 I was reading the introduction at
 http://www.haskell.org/haskellwiki/Introduction
 where the typical Haskell version of qsort is given

 qsort [] = []
 qsort (x:xs) = qsort
 (filterhttp://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html
#v:filter ( x) xs)
 ++http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:.
 [x]
 ++http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:.
qsort
 (filterhttp://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html
#v:filter
 (=http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:;
gt;=x ) xs

 which is then compared to the inplace C version, showing off how much
 shorter the Haskell version is.

 However, the page also has a link to a semi-direct translation of the C
 version, which then brings the user to all kinds of confusing threads and
 texts, like

 ***Unfortunately none of the above real quicksorts seems to compile as
 given, when copy/pasted into ghci. Can someone fix? The parallel
 quicksort gave error unknown package concurrent when I ran make in
 quicksort/gransim. Has anyone got a functioning real quicksort that works
 on copy/paste? The program below is working very very slowly. It's probably
 slowsort... :o)*
 *
 *
 Furthermore the inplace versions of qsort in Haskell are IMO less readable
 than the C version.

 I'm not sure but if I would be a beginner I might get confused by this.

Okay, the more direct translation of the C code

--
import Data.Array.Base (unsafeRead, unsafeWrite)
import Data.Array.ST
import Control.Monad.ST

myqsort :: STUArray s Int Int - Int - Int - ST s ()
myqsort a lo hi
| lo  hi   = do
let lscan p h i
| i  h = do
v - unsafeRead a i
if p  v then return i else lscan p h (i+1)
| otherwise = return i
rscan p l i
| l  i = do
v - unsafeRead a i
if v  p then return i else rscan p l (i-1)
| otherwise = return i
swap i j = do
v - unsafeRead a i
unsafeRead a j = unsafeWrite a i
unsafeWrite a j v
sloop p l h
| l  h = do
l1 - lscan p h l
h1 - rscan p l1 h
if (l1  h1) then (swap l1 h1  sloop p l1 h1) else return 
l1
| otherwise = return l
piv - unsafeRead a hi
i - sloop piv lo hi
swap i hi
myqsort a lo (i-1)
myqsort a (i+1) hi
| otherwise = return ()


doesn't sacrifice performance for polymorphism (the C code isn't polymorphic 
either) - in 
my tests, it took less than twice the time the C code took to sort the same 
array, not too 
bad.

It compiles as is, and if it satisfies readability requirements, somebody can 
put it on 
the wiki.


 It is often claimed that compiler technology will make it possible to
 compile high level code into efficient low level code that is almost as
 efficient as the C or asm routines. How does this apply to qsort today?

If you give it a chance to optimise, it isn't too bad.
The code from the wiki takes about three times as long as the code above,
** if it's compiled
a) with -O2 and
b) in a setting where it specialises to the appropriate unboxed array type, be 
it by 
giving {-# SPECIALISE #-} pragmas or by having the code in the same module as 
the use 
(with a good type, e.g. STUArray s Int Int) **.

If you disable optimisations by requiring fully polymorphic code and only that, 
the factor 
is about 80.


 Cheers,
 Peter Verswyvelen

___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe