user4596: Context
I'm creating scripts with hardcoded parameters in my smartcontract and I would like to reduce footprint of them to reduce transaction fees. Right now i'm doing so using parameterized smartcontracts. I can't provide source but I read or heard somewhere that using parameterized smartcontracts use up a lot of ExMemory. When building plutus scripts i'm using evaluateScriptCounting which after compilation shows me ExCPU and ExMemory of my script. So far I have found the only way to hardcode parameters without using parameterized smartcontracts with BuiltinByteStrings is doing something like this:
{-# INLINABLE flattenBuiltinByteString #-}
flattenBuiltinByteString :: [BuiltinByteString] -> BuiltinByteString
flattenBuiltinByteString [] = emptyByteString 
flattenBuiltinByteString (x:xs) = appendByteString x (flattenBuiltinByteString xs)

{-# INLINABLE getPkh #-}
getPkh :: PubKeyHash
getPkh = PubKeyHash { getPubKeyHash = flattenBuiltinByteString [ consByteString x emptyByteString |x <- [128,164,244,91,86,184,141,17,57,218,35,188,76,60,117,236,109,50,148,60,8,127,37,11,134,25,60,167]]}

I was expecting that this way I would get lower ExCPU and ExMemory units. But I did some tests and to my surprise my smartcontract without parameterized parameters was bigger!
Tests

ExCPU -> 8366313, ExMemory -> 28200. Plain always succeeds.
ExCPU -> 8366313, ExMemory -> 28200. BuiltinByteString, no checks, no datum.
ExCPU -> 9080865, ExMemory -> 30600. Parameterized no checks, no datum.
ExCPU -> 9438141, ExMemory -> 31800. Parameterized no checks, added typed datum with 4 fields.
ExCPU -> 10152693, ExMemory -> 34200. Parameterized 4 checks against typed datum.
ExCPU -> 11135202, ExMemory -> 37500. BuiltinByteString 4 checks against typed datum.

Questions

My flattenBuiltinByteString is doing the flattening foldr style which is ineffective and I suppose is why i'm having such big jump in ExMemory units. I was looking for foldl' in Plutus library but couldn't find anything. Does Plutus have something simillar to seq so that I could make my own foldl' implementation?
Are there other more effective ways to flatten BuiltinByteString list on-chain?
What over tricks I could do besides using BuiltinData types instead of my own custom typed data types to optimize my smartcontracts?
Should I even be bothering with optimizations like this, whats the upper ExCPU and ExMemory limit?


user5085: I am building a dApp myself and I am running into similar issues related to hitting the current mainnet's maxTxExUnits upper boundaries of exUnitsMem and exUnitsSteps.
In regards to question 4:
You can find the current upper limits by querying your cardano node for protocol parameters like so:
cardano-cli query protocol-parameters $MAGIC --out-file protocol-parameters.json

The limits can be found under: maxTxExecutionUnits
I resolved some of my issues related to exceeding the ExMemory upper limit by:

simplifying/ optimizing the contract logic
removing traceIfFalse statements or at least decreasing long log message string down to error codes
using Bang Pattern in let-bindings
avoid exhaustive case patterns and instead rely on Plutus' throwing an error for a missing pattern match

There are many more resources you can read below for further possible code improvements to optimize your script.
Sources:

MinSwap Article
Plutonomicon


4596: <h1>Context</h1>
<p>I'm creating scripts with hardcoded parameters in my smartcontract and I would like to reduce footprint of them to reduce transaction fees. Right now i'm doing so using <em>parameterized smartcontracts</em>. I can't provide source but I read or heard somewhere that using <em>parameterized smartcontracts</em> use up a lot of <strong>ExMemory</strong>. When building plutus scripts i'm using <code>evaluateScriptCounting</code> which after compilation shows me <strong>ExCPU</strong> and <strong>ExMemory</strong> of my script. So far I have found the only way to hardcode parameters without using <em>parameterized smartcontracts</em> with <code>BuiltinByteString</code>s is doing something like this:</p>
<pre><code>{-# INLINABLE flattenBuiltinByteString #-}
flattenBuiltinByteString :: [BuiltinByteString] -&gt; BuiltinByteString
flattenBuiltinByteString [] = emptyByteString 
flattenBuiltinByteString (x:xs) = appendByteString x (flattenBuiltinByteString xs)

{-# INLINABLE getPkh #-}
getPkh :: PubKeyHash
getPkh = PubKeyHash { getPubKeyHash = flattenBuiltinByteString [ consByteString x emptyByteString |x &lt;- [128,164,244,91,86,184,141,17,57,218,35,188,76,60,117,236,109,50,148,60,8,127,37,11,134,25,60,167]]}
</code></pre>
<p>I was expecting that this way I would get lower <strong>ExCPU</strong> and <strong>ExMemory</strong> units. But I did some tests and to my surprise my smartcontract without parameterized parameters was bigger!</p>
<h1>Tests</h1>
<ol>
<li>ExCPU -&gt; 8366313, ExMemory -&gt; 28200. Plain always succeeds.</li>
<li>ExCPU -&gt; 8366313, ExMemory -&gt; 28200. BuiltinByteString, no checks, no datum.</li>
<li>ExCPU -&gt; 9080865, ExMemory -&gt; 30600. Parameterized no checks, no datum.</li>
<li>ExCPU -&gt; 9438141, ExMemory -&gt; 31800. Parameterized no checks, added typed datum with 4 fields.</li>
<li>ExCPU -&gt; 10152693, ExMemory -&gt; 34200. Parameterized 4 checks against typed datum.</li>
<li>ExCPU -&gt; 11135202, ExMemory -&gt; 37500. BuiltinByteString 4 checks against typed datum.</li>
</ol>
<h1>Questions</h1>
<ol>
<li>My <code>flattenBuiltinByteString</code> is doing the flattening <code>foldr</code> style which is ineffective and I suppose is why i'm having such big jump in <strong>ExMemory</strong> units. I was looking for <code>foldl'</code> in Plutus library but couldn't find anything. Does Plutus have something simillar to <code>seq</code> so that I could make my own <code>foldl'</code> implementation?</li>
<li>Are there other more effective ways to flatten <code>BuiltinByteString</code> list on-chain?</li>
<li>What over tricks I could do besides using <code>BuiltinData</code> types instead of my own custom typed data types to optimize my smartcontracts?</li>
<li>Should I even be bothering with optimizations like this, whats the upper <strong>ExCPU</strong> and <strong>ExMemory</strong> limit?</li>
</ol>
 5085: <p>I am building a dApp myself and I am running into similar issues related to hitting the current mainnet's <code>maxTxExUnits</code> upper boundaries of <code>exUnitsMem</code> and <code>exUnitsSteps</code>.</p>
<p><strong>In regards to question 4</strong>:</p>
<p>You can find the current upper limits by querying your cardano node for protocol parameters like so:</p>
<pre><code>cardano-cli query protocol-parameters $MAGIC --out-file protocol-parameters.json
</code></pre>
<p>The limits can be found under: <code>maxTxExecutionUnits</code></p>
<p>I resolved some of my issues related to exceeding the ExMemory upper limit by:</p>
<ul>
<li>simplifying/ optimizing the contract logic</li>
<li>removing <code>traceIfFalse</code> statements or at least decreasing long log message string down to error codes</li>
<li>using <strong>Bang Pattern</strong> in let-bindings</li>
<li>avoid exhaustive case patterns and instead rely on Plutus' throwing an error for a missing pattern match</li>
</ul>
<p>There are many more resources you can read below for further possible code improvements to optimize your script.</p>
<p>Sources:</p>
<ul>
<li><a href="https://minswap-labs.medium.com/tech-drips-1-optimizing-plutus-script-to-reduce-fees-and-increase-throughput-db6cce65c959" rel="nofollow noreferrer">MinSwap Article</a></li>
<li><a href="https://github.com/Plutonomicon/plutonomicon/blob/main/scriptmem.md" rel="nofollow noreferrer">Plutonomicon</a></li>
</ul>
