I am working on a terrain generation algorithm for a world like MineCraft. I am currently using simplex noise based on the implementation in the article "Simplex Noise Demystified" [PDF] , because it is assumed that simplex noise is faster and have fewer artifacts than Perlin noise. It looks pretty decent (see image), but so far it is also pretty slow.

Launching the noise function 10 times (I need noise with different wavelengths for things like surface height, temperature, location of trees, etc.) with 3 octaves of noise for each block in a piece (16x16x128 blocks) or about 1 million calls per noisy function in general, takes about 700-800 ms. This is at least an order of magnitude slower in order to create a terrain at any decent speed, despite the fact that the algorithm does not have obvious expensive operations (at least for me). Just gender, modulo, some search engines and basic arithmetic. The algorithm (written in Haskell) is given below. SCC comments are for profiling. I omitted the 2D noise functions, as they work the same.
g3 :: (Floating a, RealFrac a) => a g3 = 1/6 {-
For profiling, I used the following code,
q _ = let p = perm 0 in sum [harmonicNoise3D p 3 lxyz :: Float | l <- [1..10], y <- [0..127], x <- [0..15], z <- [0..15]] main = do start <- getCurrentTime print $ q () end <- getCurrentTime print $ diffUTCTime end start
which gives the following information:
COST CENTRE MODULE %time %alloc simplex3D Main 18.8 21.0 n Main 18.0 19.6 out Main 10.1 9.2 harmonicNoise3D Main 9.8 4.5 harmonic Main 6.4 5.8 int Main 4.0 2.9 gi3 Main 4.0 3.0 xyz2 Main 3.5 5.9 gi1 Main 3.4 3.4 gi0 Main 3.4 2.7 fastFloor Main 3.2 0.6 xyz1 Main 2.9 5.9 ijk Main 2.7 3.5 gi2 Main 2.7 3.3 xyz3 Main 2.6 4.1 iijjkk Main 1.6 2.5 dot3 Main 1.6 0.7
To compare, I also ported the algorithm to C #. Performance there is about 3-4 times faster, so I think I should be doing something wrong. But even then it is not as fast as we would like. So my question is this: can someone tell me if there are ways to speed up my implementation and / or the algorithm in general, or does anyone know of another noise algorithm that has better performance characteristics but a similar look?
Update:
After fulfilling some of the suggestions below, the code looks as follows:
module Noise ( Permutation, perm , noise3D, simplex3D ) where import Data.Bits import qualified Data.Vector.Unboxed as UV import System.Random import System.Random.Shuffle type Permutation = UV.Vector Int g3 :: Double g3 = 1/6 {-
Along with reducing the size of my piece to 8x8x128, the generation of new relief fragments now occurs at a speed of about 10-20 frames per second, which means that moving is now not as problematic as before. Of course, any other performance improvements are still welcome.