Question on the efficiency of binding record values to variables

Suppose I have the following record type and a constructed value of that type:

data Point = P
    { x :: Double
    , y :: Double
    }
point = P {x = 1, y = 2}

and I want to bind x and y values of this point to new variables px and py. Which of the following two versions is more efficient?

P {x = px, y = py} = point

or

px = x point
py = y point

So far I have always used the latter variant because I did not know the first variant. Am I correct in assuming that the first variant is more efficient since both values are bound at once?

I’d like to point out that, as well as using record syntax like this:

point = P {x = 1, y = 2}
P {x = px, y = py} = point

If you are assigning to or from all of the fields, you can also just do this:

point = P 1 2
P px py = point

I don’t know which compiles to more efficient output. I’d imagine that any differences between the versions would be easy to optimise out, making them all the same, but that’s just a guess.

1 Like

My guess is that it gets optimized by the compiler and no difference (in efficiency) will show up.

Consider this example:

point = P 3 4
a = point
b = a
P c d = b
e = P c d
f = e
putStrln $ show f

I believe it produces the same executable as

putStrln $ show (P 3 4)

Maybe some ghc/optimisation guru can chime in and confirm: there is no “execution” here

In your assumption “since both values are bound at once?”, you may overlook that binding may be a compile-time trick, not an execution-time, CPU-consuming operation

1 Like

As others have guessed (and I just checked), both versions are exactly the same at runtime. What’s more, the runtime cost is zero in both cases. :slight_smile: All you’re doing is creating different names for existing values — useful for humans, but unnecessary for machines. It’s not like any memory is getting passed around or anything.

5 Likes