Yes, there is a performance difference:
A (23, 42) will contain a tag identifying it as an
A and the two integers 23 and 42.
B (23, 42) will contain a tag identifying it as a
B and a pointer to a tuple containing the integers
42. So there will be one additional memory allocation when creating a
B and one additional level of indirection when accessing the individual values inside a
B. So in cases where you don't actually use the constructor arguments as a tuple, using
A will involve less overhead than using
On the other hand your
test_foo function will create a new tuple every time it is called with an
A value, but when it is called with a
B value it will simply return the tuple that already exists in memory. So
test_foo is a cheaper operation for
B than it is for
A. So if you'll be using the constructor's arguments as a tuple and you will do so multiple times for the same value, using
B will be cheaper.
So if you're going to be using the constructor arguments as a tuple, it makes sense to use a constructor taking a tuple because you can get at the tuple using pattern matching with less code and because it will avoid having to create tuples from the same value multiple times. In all other cases not using a tuple is preferable because it involves less memory allocation and less indirection.