<p>Copying my answer from the Github issue here as well:</p>
<p>We have hit the same issue lately. It is due to how the <code>==</code> function in the <code>Eq Value</code> instance is implemented.</p>
<p>A value is logically a <code>Map CurrencySymbol (Map TokenName Quantity)</code>, but on-chain there are no maps. Instead associative lists are used instead. As a Haskell type, a <code>Value</code> would be something like <code>[(CurrencySymbol, [(TokenName, Quantity)]]</code>.</p>
<p>This means that given two values with the same contents, they may not be <em>exactly</em> the same if you compare them element by element. (I assume) the implementation of <code>Eq Value</code> was intended to mitigate this by implementing a Map-like equality. While correct, it turns out, this is quite an expensive implementation.</p>
<p>What we have opted for is an &quot;exact equality&quot; check for <code>Value</code> in the Hydra code base: <a href="https://github.com/input-output-hk/hydra/pull/709" rel="nofollow noreferrer">https://github.com/input-output-hk/hydra/pull/709</a> (We investigated and indeed serializing to bytes and comparing the results was most efficient for us with complexity of about O(2n) or so)</p>
<p>I think we should discuss the need for such an exact equality function and maybe guide users more towards that if just want to ensure values are exactly the same / unchanged? From my experience this is often good enough and could be implemented cheaper.</p>

CC BY-SA 4.0
2023-02-20T02:41:48.887Z
Can you tell me about the limits of your idea on comparing values with the serialized data, the "exact equality"? When it will work and when it wont? 
Im in process of comparing results of your idea with the idea I proposed for check equality.
This is my idea, could be wrong or not enough good, but its better than the actual one. Can you spot any inconvenient using my proposal?

https://github.com/input-output-hk/plutus/issues/5135#issuecomment-1436071599
Manu Padilla
CC BY-SA 4.0
2023-02-21T08:38:47.770Z
Using `serialiseData` it will only be equal if the all the contents are *exactly* the same. That is, same elements, in the same order and no duplicates (or same duplicates).
Sebastian Nagel
CC BY-SA 4.0
2023-02-22T23:25:18.140Z
In maps, can we have two elements with the same key? in the case of VALUES, can we have two equals currency symbols or two equals token name in the maps inside each currency symbol?
Manu Padilla
CC BY-SA 4.0
2023-02-24T15:06:52.130Z
There are no maps on chain, they are association lists as I described in my answer above. So yes, multiple pairs with same key can be in there.
Sebastian Nagel
CC BY-SA 4.0
2023-02-24T15:45:22.660Z
thank you for all the answers! Lets see how this evolves!
Manu Padilla
CC BY-SA 4.0
2023-02-28T16:02:26.760Z
Sebastian, I have still a question about this. Would you give me a concrete example of a transaction where it can fail the exactly equality?
Given a transaction with one input and one output, I need to compare the VALUES of them. In witch cases it can fail?
Manu Padilla
CC BY-SA 4.0
2023-02-14T07:49:33.517Z
2023-02-14T07:49:33.517Z
Sebastian Nagel
<p>I found an strange consumption of mem and CPU when comparting VALUES on-chain.</p>
<p>If I do the same comparison with my own writing functions I found is more efficient. How could it be?</p>
<p>Everything is detailed here:
<a href="https://github.com/input-output-hk/plutus/issues/5135" rel="nofollow noreferrer">https://github.com/input-output-hk/plutus/issues/5135</a></p>
<p>Basically, I run some test evaluations over two different minting policies. One using the (==) operator between VALUES and other using my own function called valueEqualsValue. The results where overwhelming.</p>
<p>With zero tokens my own functions use 12% less of resources and with 19 different tokens they use 32% less than the officials one.</p>
<p>It could be I'm missing some functionality in the comparison, that is implemented in the official one with the (==) operator. I found also benefits like this writing my own version of flattenValue.</p>
<p>How do you compare VALUES online?</p>
<p>Did you notice this unexpected inefficiency in some of other core functionalities of Plutus On Chain Code?</p>
<p>Considering the limited amount of memory that we have to write our smart contracts its very strange for me to realize that even the most basic functionalities they look very inefficient.</p>
<p>Thank you</p>

<plutus><on-chain>
Overuse of resources when comparing for equality of VALUES (==)
# Overuse of resources when comparing for equality of VALUES (==)

(Asked by: username_0 on 2023-02-13)

I found an strange consumption of mem and CPU when comparting VALUES on-chain.

If I do the same comparison with my own writing functions I found is more efficient. How could it be?

Everything is detailed here:
<https://github.com/input-output-hk/plutus/issues/5135>

Basically, I run some test evaluations over two different minting policies. One using the (==) operator between VALUES and other using my own function called valueEqualsValue. The results where overwhelming.

With zero tokens my own functions use 12% less of resources and with 19 different tokens they use 32% less than the officials one.

It could be I'm missing some functionality in the comparison, that is implemented in the official one with the (==) operator. I found also benefits like this writing my own version of flattenValue.

How do you compare VALUES online?

Did you notice this unexpected inefficiency in some of other core functionalities of Plutus On Chain Code?

Considering the limited amount of memory that we have to write our smart contracts its very strange for me to realize that even the most basic functionalities they look very inefficient.

Thank you

**Tags:** plutus, on-chain

---

## 1 answers

### Answer by username_1 on 2023-02-14. Score: 3 | Accepted answer

Copying my answer from the Github issue here as well:

We have hit the same issue lately. It is due to how the `==` function in the `Eq Value` instance is implemented.

A value is logically a `Map CurrencySymbol (Map TokenName Quantity)`, but on-chain there are no maps. Instead associative lists are used instead. As a Haskell type, a `Value` would be something like `[(CurrencySymbol, [(TokenName, Quantity)]]`.

This means that given two values with the same contents, they may not be *exactly* the same if you compare them element by element. (I assume) the implementation of `Eq Value` was intended to mitigate this by implementing a Map-like equality. While correct, it turns out, this is quite an expensive implementation.

What we have opted for is an "exact equality" check for `Value` in the Hydra code base: <https://github.com/input-output-hk/hydra/pull/709> (We investigated and indeed serializing to bytes and comparing the results was most efficient for us with complexity of about O(2n) or so)

I think we should discuss the need for such an exact equality function and maybe guide users more towards that if just want to ensure values are exactly the same / unchanged? From my experience this is often good enough and could be implemented cheaper.

> **Comments:**
> **username_0**: Can you tell me about the limits of your idea on comparing values with the serialized data, the "exact equality"? When it will work and when it wont?  Im in process of comparing results of your idea with the idea I proposed for check equality. This is my idea, could be wrong or not enough good, but its better than the actual one. Can you spot any inconvenient using my proposal?  https://github.com/input-output-hk/plutus/issues/5135#issuecomment-1436071599  
> **username_1**: Using `serialiseData` it will only be equal if the all the contents are *exactly* the same. That is, same elements, in the same order and no duplicates (or same duplicates).  
> **username_0**: In maps, can we have two elements with the same key? in the case of VALUES, can we have two equals currency symbols or two equals token name in the maps inside each currency symbol?  
> **username_1**: There are no maps on chain, they are association lists as I described in my answer above. So yes, multiple pairs with same key can be in there.  
> **username_0**: thank you for all the answers! Lets see how this evolves!  
> **username_0**: Sebastian, I have still a question about this. Would you give me a concrete example of a transaction where it can fail the exactly equality? Given a transaction with one input and one output, I need to compare the VALUES of them. In witch cases it can fail?  

---

