I implemented binary tree data structure in Haskell.
My code:
module Data.BTree where
data Tree a = EmptyTree
| Node a (Tree a) (Tree a)
deriving (Eq, Ord, Read, Show)
emptyTree :: a -> Tree a
emptyTree a = Node a EmptyTree EmptyTree
treeInsert :: (Ord a) => a -> Tree a -> Tree a
treeInsert x EmptyTree = emptyTree x
treeInsert x (Node a left right)
| x == a = (Node x left right)
| x < a = (Node a (treeInsert x left) right)
| x > a = (Node a left (treeInsert x right))
fillTree :: Int -> Tree Int -> Tree Int
fillTree 10000 tree = tree
fillTree x tree = let a = treeInsert x tree
in fillTree (x + 1) a
This code very slow. I run:
fillTree 1 EmptyTree
I get : 50.24 secs
I try to implement this code in C language and my result of this test: 0m0.438s
Why so big difference? Is Haskell code rely so slow or my binary tree in haskell bad? I want to ask haskell guru maybe i can make my binary tree implementation more effective?
Thank you.
I doubt you implemented the same code in C. You probably used a non-persistent tree structure instead.
That means you’re comparing an O(n^2) algorithm in Haskell to an O(n) algorithm in C.Nevermind, the specific case you’re using would be O(n^2) with a persistent structure or not. There’s just a lot more allocation with the persistent structure, so it’s not a fundamental algorithmic difference.Additionally, it looks like you ran this from ghci. That ‘i’ in “ghci” means “interpreter”. And yes, the interpreter can be tens or hundreds of times slower than compiled code. Try compiling it with optimizations and running it.
I suspect it’ll still be slower due to fundamental algorithmic differences, but it won’t be near 50 seconds.