Position of arguments in function definition and performance
Hello. Please, tell me which set of definitions below should I expected to be more efficient: the reverse1 or the reverse2 functions. reverse1 [] ys = ys reverse1 (x:xs) ys = reverse2 (x:ys) xs reverse2 ys [] = ys reverse2 ys (x:xs) = reverse2 (x:ys) xs The difference rely on the position of the argument in which the pattern matching is done in the function definition. Regards. Romildo -- Prof. José Romildo Malaquias Departamento de Computação http://iceb.ufop.br/~romildo Universidade Federal de Ouro Preto romildo@iceb.ufop.br Brasil romildo@uber.com.br
Well, I assume you meant: reverse1 [] ys = ys reverse1 (x:xs) ys = reverse1 xs (x:ys) reverse2 ys [] = ys reverse2 ys (x:xs) = reverse1 (x:ys) xs If so, and you make two programs: main = print (length $! reverse1 [1..2000000] []) and main = print (length $! reverse2 [] [1..2000000]) compile them with ghc -O2 -fvia-c, and time them we get: FOR REVERSE1: 11:42pm enescu:~/ time a.out 2000000 4.84u 0.28s 0:06.01 85.1% 11:42pm enescu:~/ time a.out 2000000 4.71u 0.24s 0:05.25 94.2% FOR REVERSE2: 11:43pm enescu:~/ time a.out 2000000 1.00u 0.03s 0:01.09 94.4% 11:43pm enescu:~/ time a.out 2000000 0.99u 0.01s 0:00.99 101.0% curiously, REVERSE2 did significantly better; I have no idea why. Perhaps one of the Simons could comment on this. Moreover, if this is a general phenomenon, why doesn't GHC simply permute the order of parameters to allow it to optimize best? Regards, Hal -- Hal Daume III "Computer science is no more about computers | hdaume@isi.edu than astronomy is about telescopes." -Dijkstra | www.isi.edu/~hdaume On Wed, 6 Feb 2002, [iso-8859-1] Jos� Romildo Malaquias wrote:
Hello.
Please, tell me which set of definitions below should I expected to be more efficient: the reverse1 or the reverse2 functions.
reverse1 [] ys = ys reverse1 (x:xs) ys = reverse2 (x:ys) xs
reverse2 ys [] = ys reverse2 ys (x:xs) = reverse2 (x:ys) xs
The difference rely on the position of the argument in which the pattern matching is done in the function definition.
Regards.
Romildo -- Prof. Jos� Romildo Malaquias Departamento de Computa��o http://iceb.ufop.br/~romildo Universidade Federal de Ouro Preto romildo@iceb.ufop.br Brasil romildo@uber.com.br _______________________________________________ Haskell mailing list Haskell@haskell.org http://www.haskell.org/mailman/listinfo/haskell
Actually, presumably you meant:
reverse2 ys (x:xs) = reverse2 (x:ys) xs
(stupid cut & paste late at night). with this fix (and now we actually are reversing the list with reverse2), we get the following timings for reverse2: 11:49pm enescu:~/ time a.out 2000000 4.64u 0.31s 0:05.18 95.5% 11:49pm enescu:~/ time a.out 2000000 4.87u 0.25s 0:06.23 82.1% which seems to say they perform comparably, as we would expect. sorry for freaking out earlier :) - Hal -- Hal Daume III "Computer science is no more about computers | hdaume@isi.edu than astronomy is about telescopes." -Dijkstra | www.isi.edu/~hdaume On Wed, 6 Feb 2002, Hal Daume III wrote:
Well, I assume you meant:
reverse1 [] ys = ys reverse1 (x:xs) ys = reverse1 xs (x:ys)
reverse2 ys [] = ys reverse2 ys (x:xs) = reverse1 (x:ys) xs
If so, and you make two programs:
main = print (length $! reverse1 [1..2000000] [])
and
main = print (length $! reverse2 [] [1..2000000])
compile them with ghc -O2 -fvia-c, and time them we get:
FOR REVERSE1:
11:42pm enescu:~/ time a.out 2000000 4.84u 0.28s 0:06.01 85.1% 11:42pm enescu:~/ time a.out 2000000 4.71u 0.24s 0:05.25 94.2%
FOR REVERSE2:
11:43pm enescu:~/ time a.out 2000000 1.00u 0.03s 0:01.09 94.4% 11:43pm enescu:~/ time a.out 2000000 0.99u 0.01s 0:00.99 101.0%
curiously, REVERSE2 did significantly better; I have no idea why. Perhaps one of the Simons could comment on this. Moreover, if this is a general phenomenon, why doesn't GHC simply permute the order of parameters to allow it to optimize best?
Regards,
Hal
-- Hal Daume III
"Computer science is no more about computers | hdaume@isi.edu than astronomy is about telescopes." -Dijkstra | www.isi.edu/~hdaume
On Wed, 6 Feb 2002, [iso-8859-1] Jos� Romildo Malaquias wrote:
Hello.
Please, tell me which set of definitions below should I expected to be more efficient: the reverse1 or the reverse2 functions.
reverse1 [] ys = ys reverse1 (x:xs) ys = reverse2 (x:ys) xs
reverse2 ys [] = ys reverse2 ys (x:xs) = reverse2 (x:ys) xs
The difference rely on the position of the argument in which the pattern matching is done in the function definition.
Regards.
Romildo -- Prof. Jos� Romildo Malaquias Departamento de Computa��o http://iceb.ufop.br/~romildo Universidade Federal de Ouro Preto romildo@iceb.ufop.br Brasil romildo@uber.com.br _______________________________________________ Haskell mailing list Haskell@haskell.org http://www.haskell.org/mailman/listinfo/haskell
_______________________________________________ Haskell mailing list Haskell@haskell.org http://www.haskell.org/mailman/listinfo/haskell
The programs: -- common part module Main where reverse1 [] ys = ys reverse1 (x:xs) ys = reverse1 xs (x:ys) reverse2 ys [] = ys reverse2 ys (x:xs) = reverse2 (x:ys) xs -- program t1 main = print (length $! reverse1 [1..2000000] []) -- program t2 main = print (length $! reverse2 [] [1..2000000]) give the following execution times in my 256MB, AMD Athlon XP 1600 based (RedHat Linux 7.2) system running ghc 5.02.2: EXECUTION TIMES COMPILER COMPILER OPTIONS t1 t2 ghc 1.503 1.516 ghc -O2 1.858 1.834 ghc -fvia-c 1.507 1.491 ghc -O2 -fvia-c 1.855 1.835 nhc98 3.734 1.559 Comments: - The compiler option -O2 with ghc leads to slight worse execution time - Execution times for t1 and t2 are similar with ghc. - t2 executes aproximately 2.4 times faster than t1 when compiled with nhc98 - t2 executation time when compiled with nh98 is as good as when compiled with ghc Conclusions: - with ghc there is no significant difference in performance when switching the position of the arguments subject to pattern matching in the function definition - with nhc98, it is better to pattern match on the last argument - surprisingly, the ghc -O2 compiler option generated code is worst than no optimization Romildo -- Prof. José Romildo Malaquias Departamento de Computação http://iceb.ufop.br/~romildo Universidade Federal de Ouro Preto romildo@iceb.ufop.br Brasil romildo@uber.com.br
participants (2)
-
Hal Daume III -
José Romildo Malaquias