How to know the size of a data type

G-d willing

Hello,
How can I know how much memory is being used for a tuple and how much for a list?
Assuming I have the code:

  let aTuple = (1,2,3,4,5)
  let aList = [1,2,3,4,5]

I would like to know how much memory was used for each one of them.

1 Like

Daml values are represented as Protobuf messages on the wire. You can see the translation here and then get information about the binary encoding here and here.

In particular, Daml integers are encoded as Protobuf int64 which is a variable length encoding. So small numbers like 1, 2, 3, 4, 5 are one byte each afaiu. Large numbers will be up to 8 bytes.

The tuple and list wrappers will add a bit to that.

1 Like

I wasn’t referring in my question to the size of Int or Decimal but more to the memory that Daml “spends” in order to manage a tuple and a list.
This question was made in order to learn about the efficiency of working with tuples and lists.

Fair enough. My answer still points to the same documentation, though.

You can read how Lists and Tuples are converted from Daml to Daml-LF. TL:DR, to a record and native constructor, respectively.

You can then read how Lists and records are encoded in profobuf.

So your list would be a proto message like

      list {
        elements {
          int64: 1
        }
        elements {
          int64: 2
        }
        elements {
          int64: 3
        }
        ...
      }

Your tuple would be something like

{
  record_id {
    package_id: "some-hash"
    name: "DA.Types.Tuple5"
  }
  fields { 
    label: "_1"
    value { 
      int64: 1
    }
  }
  fields { 
    label: "_2"
    value { 
      int64: 2
    }
  }
  fields { 
    label: "_3"
    value { 
      int64: 3
    }
  }
  ...
  }

Then you can look at the protobuf docs to see how many bytes that takes, respectively. List is more efficient, but I can’t tell you by how much.

1 Like

Let me extend a bit the answer of @bernhard.

Because tuples are actually encoded as records, I will consider records instead of tuples in the following.

The protobuf @bernhard is referring to is the one used to encode values on the ledger API. Note that if you do not use the verbose mode, the fields record_id and label will not be set, meaning your record will have only a small constant overhead for w.r.t. your list.

To store the values in the ledger or to send transactions to other participants, we actually use a different though similar protobuf. Except for very old Daml-LF versions, records are encoding without type annotation nor field names similarly as for the ledger API non-verbose mode, so using records requires only a bit more memory than using lists.

In my opinion the different in space should be negligible enough to be simply ignored in most of the cases.

1 Like