Skip to content

Add Data.Constr casing to Case - #7914

Open
SeungheonOh wants to merge 12 commits into
masterfrom
sho/caseDataConstr
Open

Add Data.Constr casing to Case#7914
SeungheonOh wants to merge 12 commits into
masterfrom
sho/caseDataConstr

Conversation

@SeungheonOh

Copy link
Copy Markdown
Contributor
case (n : data) of 
  Data.Constr 1 xs -> ...
  Data.Constr 2 xs -> ...
  Data.Constr 3 xs -> ...
  Data.Constr 4 xs -> ...

I discarded this idea originally as most of the cost would've been in the deconstruction of fields(xs here). However, introduction of DropList made deconstruction of xs reasonable fast so this approach actually gives a decent performance boost with minimal change!

@SeungheonOh
SeungheonOh requested review from a team and zliu41 August 20, 2026 05:52
@SeungheonOh SeungheonOh self-assigned this Aug 20, 2026
@github-actions

github-actions Bot commented Aug 20, 2026

Copy link
Copy Markdown
Contributor

Execution Budget Golden Diff

f424a79 (master) vs 894db47

output

fatal: bad object f424a79

This comment will get updated when changes are made.

{-# OPAQUE wrapUnsafeDataAsConstr #-}

wrapCaseData :: BuiltinData -> [BuiltinList BuiltinData -> a] -> a
wrapCaseData = BI.caseData

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are you sure we need this? It's possible that neither this nor wrapUnsafeDataAsConstr is needed any more.

If we do, then this needs to be mentioned in the Note below.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we don't have this, inliner won't inline the bindings it makes for each fields which prevents DeadCase and CollapseCase pass from running. Can't really think of other ways to make this work better

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On the side note, this method only works on quite specific case where each handler of the match must be lambda directly like so:

matchRich ...
  (\a b c -> ...)
  (\x y z k -> ...)
  ...

if we have non-lambda handler, this doesn't work at all!

let f = \a b c -> ...
in matchRich ...
     f
     (\x y z k -> ...)
     ...

All fields gets bounded for f.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could retire the matcher and try to optimize pattern matching in the plugin. The matcher is already inconvenient to begin with, compared to direct pattern matching. May not be easy to do though.

@zliu41 zliu41 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It otherwise looks good, but this new feature must be gated by dijkstraPV, and I don't think it is gated properly.

@SeungheonOh

Copy link
Copy Markdown
Contributor Author

Do we need this to be gated by dijkstra? I don't think adding this to older PV with builtin casing would have any issue. What do you think?

@zliu41

zliu41 commented Aug 20, 2026

Copy link
Copy Markdown
Member

Do we need this to be gated by dijkstra?

Yes otherwise old node version rejects casing on Constr, new node version accepts it.

Comment thread plutus-ledger-api/src/PlutusLedgerApi/Common/Case.hs Outdated
-> HeadSpine Text term (Some (ValueOf DefaultUni))
caseBuiltinDataUnavailable someVal@(Some (ValueOf uni x)) branches = case uni of
DefaultUniUnit
| 1 == len -> HeadOnly $ branches Vector.! 0

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think you need to duplicate the code for each branch. Can you not call caseBuiltin here?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This would make it slower! aruond 5~10%

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you try some refactoring, such as defining a caseBuiltinForPV that takes PV as an argument? Explicit code duplication should rarely be needed for efficiency, and should be the last resort.

@zliu41

zliu41 commented Aug 25, 2026

Copy link
Copy Markdown
Member

You may also want to check if any of the conformance tests need to be updated.

@zliu41

zliu41 commented Sep 1, 2026

Copy link
Copy Markdown
Member

Do we have a benchmark that covers casing on constants? If so can you run it on this PR to ensure there isn't regression.

@SeungheonOh

Copy link
Copy Markdown
Contributor Author

/benchmark validation

@SeungheonOh

Copy link
Copy Markdown
Contributor Author

/benchmark casing

@github-actions

github-actions Bot commented Sep 3, 2026

Copy link
Copy Markdown
Contributor

Click here to check the status of your benchmark.

@github-actions

github-actions Bot commented Sep 3, 2026

Copy link
Copy Markdown
Contributor

Comparing benchmark results of 'validation' on 'f424a79ad' (base) and '894db473c' (PR)

Results table
Script f424a79 894db47 Change
auction_1-1 169.1 μs 166.4 μs -1.6%
auction_1-2 546.0 μs 541.4 μs -0.8%
auction_1-3 541.0 μs 536.9 μs -0.8%
auction_1-4 220.5 μs 216.5 μs -1.8%
auction_2-1 169.3 μs 166.3 μs -1.8%
auction_2-2 544.0 μs 541.2 μs -0.5%
auction_2-3 707.2 μs 702.8 μs -0.6%
auction_2-4 541.4 μs 537.7 μs -0.7%
auction_2-5 220.2 μs 216.6 μs -1.6%
coop-1 232.7 μs 226.8 μs -2.5%
coop-2 732.1 μs 713.1 μs -2.6%
coop-3 2.039 ms 1.973 ms -3.2%
coop-4 920.3 μs 892.3 μs -3.0%
coop-5 399.6 μs 388.6 μs -2.8%
coop-6 682.7 μs 658.4 μs -3.6%
coop-7 329.4 μs 319.0 μs -3.2%
crowdfunding-success-1 199.4 μs 196.6 μs -1.4%
crowdfunding-success-2 199.2 μs 195.9 μs -1.7%
crowdfunding-success-3 199.5 μs 195.5 μs -2.0%
currency-1 218.6 μs 216.4 μs -1.0%
escrow-redeem_1-1 311.8 μs 309.7 μs -0.7%
escrow-redeem_1-2 312.0 μs 309.6 μs -0.8%
escrow-redeem_2-1 362.0 μs 359.4 μs -0.7%
escrow-redeem_2-2 363.2 μs 357.8 μs -1.5%
escrow-redeem_2-3 362.7 μs 358.6 μs -1.1%
escrow-refund-1 147.2 μs 145.5 μs -1.2%
future-increase-margin-1 218.7 μs 217.0 μs -0.8%
future-increase-margin-2 468.5 μs 462.7 μs -1.2%
future-increase-margin-3 468.8 μs 462.9 μs -1.3%
future-increase-margin-4 420.3 μs 417.8 μs -0.6%
future-increase-margin-5 704.9 μs 704.6 μs -0.0%
future-pay-out-1 218.8 μs 216.9 μs -0.9%
future-pay-out-2 467.9 μs 462.4 μs -1.2%
future-pay-out-3 468.1 μs 461.9 μs -1.3%
future-pay-out-4 704.6 μs 702.4 μs -0.3%
future-settle-early-1 218.3 μs 216.8 μs -0.7%
future-settle-early-2 468.0 μs 462.6 μs -1.2%
future-settle-early-3 468.6 μs 462.3 μs -1.3%
future-settle-early-4 536.3 μs 533.2 μs -0.6%
game-sm-success_1-1 343.1 μs 337.5 μs -1.6%
game-sm-success_1-2 188.1 μs 187.5 μs -0.3%
game-sm-success_1-3 545.2 μs 542.6 μs -0.5%
game-sm-success_1-4 218.0 μs 216.5 μs -0.7%
game-sm-success_2-1 342.8 μs 337.8 μs -1.5%
game-sm-success_2-2 188.2 μs 187.2 μs -0.5%
game-sm-success_2-3 545.4 μs 541.0 μs -0.8%
game-sm-success_2-4 217.8 μs 216.7 μs -0.5%
game-sm-success_2-5 548.7 μs 543.8 μs -0.9%
game-sm-success_2-6 217.6 μs 216.6 μs -0.5%
guardrail-sorted-large 443.7 μs 424.0 μs -4.4%
guardrail-sorted-small 70.93 μs 70.02 μs -1.3%
guardrail-unsorted-large 603.5 μs 582.6 μs -3.5%
guardrail-unsorted-small 68.94 μs 67.38 μs -2.3%
multisig-sm-01 346.6 μs 344.1 μs -0.7%
multisig-sm-02 338.3 μs 335.7 μs -0.8%
multisig-sm-03 337.2 μs 333.9 μs -1.0%
multisig-sm-04 342.5 μs 337.3 μs -1.5%
multisig-sm-05 476.1 μs 469.8 μs -1.3%
multisig-sm-06 345.3 μs 343.6 μs -0.5%
multisig-sm-07 339.1 μs 335.3 μs -1.1%
multisig-sm-08 341.4 μs 339.3 μs -0.6%
multisig-sm-09 340.6 μs 338.7 μs -0.6%
multisig-sm-10 475.1 μs 469.8 μs -1.1%
ping-pong-1 288.5 μs 287.3 μs -0.4%
ping-pong-2 289.1 μs 286.1 μs -1.0%
ping-pong_2-1 181.5 μs 179.2 μs -1.3%
prism-1 158.4 μs 156.3 μs -1.3%
prism-2 359.1 μs 357.2 μs -0.5%
prism-3 330.1 μs 324.5 μs -1.7%
pubkey-1 136.0 μs 134.2 μs -1.3%
stablecoin_1-1 830.7 μs 826.4 μs -0.5%
stablecoin_1-2 184.0 μs 183.7 μs -0.2%
stablecoin_1-3 951.4 μs 947.6 μs -0.4%
stablecoin_1-4 194.8 μs 194.8 μs 0.0%
stablecoin_1-5 1.217 ms 1.211 ms -0.5%
stablecoin_1-6 241.3 μs 239.3 μs -0.8%
stablecoin_2-1 829.4 μs 823.1 μs -0.8%
stablecoin_2-2 183.7 μs 183.2 μs -0.3%
stablecoin_2-3 951.4 μs 949.9 μs -0.2%
stablecoin_2-4 195.3 μs 194.1 μs -0.6%
token-account-1 167.9 μs 166.6 μs -0.8%
token-account-2 295.6 μs 292.5 μs -1.0%
uniswap-1 346.9 μs 344.4 μs -0.7%
uniswap-2 198.8 μs 197.4 μs -0.7%
uniswap-3 1.519 ms 1.511 ms -0.5%
uniswap-4 310.9 μs 307.0 μs -1.3%
uniswap-5 1.016 ms 1.012 ms -0.4%
uniswap-6 296.2 μs 293.0 μs -1.1%
vesting-1 304.3 μs 301.5 μs -0.9%
f424a79 894db47 Change
TOTAL 37.70 ms 37.25 ms -1.2%

@github-actions

github-actions Bot commented Sep 3, 2026

Copy link
Copy Markdown
Contributor

Click here to check the status of your benchmark.

@github-actions

github-actions Bot commented Sep 3, 2026

Copy link
Copy Markdown
Contributor

Comparing benchmark results of 'casing' on 'f424a79ad' (base) and '894db473c' (PR)

Results table
Script f424a79 894db47 Change
casing/pairFstSnd/2000 589.7 μs 585.0 μs -0.8%
casing/pairFstSnd/4000 1.295 ms 1.279 ms -1.2%
casing/pairFstSnd/6000 2.159 ms 2.139 ms -0.9%
casing/pairFstSnd/8000 3.089 ms 3.052 ms -1.2%
casing/pairFstSnd/10000 4.091 ms 4.048 ms -1.1%
casing/pairFstSnd/12000 4.959 ms 4.898 ms -1.2%
casing/pairCasing/2000 340.2 μs 340.5 μs +0.1%
casing/pairCasing/4000 801.6 μs 801.0 μs -0.1%
casing/pairCasing/6000 1.455 ms 1.451 ms -0.3%
casing/pairCasing/8000 2.239 ms 2.228 ms -0.5%
casing/pairCasing/10000 3.092 ms 3.067 ms -0.8%
casing/pairCasing/12000 3.968 ms 3.949 ms -0.5%
casing/chooseUnit/2000 243.3 μs 226.3 μs -7.0%
casing/chooseUnit/4000 525.4 μs 504.6 μs -4.0%
casing/chooseUnit/6000 873.0 μs 828.9 μs -5.1%
casing/chooseUnit/8000 1.288 ms 1.210 ms -6.1%
casing/chooseUnit/10000 1.776 ms 1.699 ms -4.3%
casing/chooseUnit/12000 2.383 ms 2.282 ms -4.2%
casing/unitCasing/2000 35.05 μs 36.83 μs +5.1%
casing/unitCasing/4000 73.66 μs 73.15 μs -0.7%
casing/unitCasing/6000 110.2 μs 102.1 μs -7.4%
casing/unitCasing/8000 146.1 μs 146.2 μs +0.1%
casing/unitCasing/10000 182.3 μs 169.5 μs -7.0%
casing/unitCasing/12000 219.3 μs 212.7 μs -3.0%
casing/headList/2000 247.3 μs 246.1 μs -0.5%
casing/headList/4000 514.0 μs 512.8 μs -0.2%
casing/headList/6000 803.1 μs 800.4 μs -0.3%
casing/headList/8000 1.120 ms 1.121 ms +0.1%
casing/headList/10000 1.476 ms 1.469 ms -0.5%
casing/headList/12000 1.872 ms 1.863 ms -0.5%
casing/headListCasing/2000 161.1 μs 155.8 μs -3.3%
casing/headListCasing/4000 345.1 μs 335.0 μs -2.9%
casing/headListCasing/6000 555.2 μs 540.1 μs -2.7%
casing/headListCasing/8000 810.0 μs 785.1 μs -3.1%
casing/headListCasing/10000 1.113 ms 1.085 ms -2.5%
casing/headListCasing/12000 1.481 ms 1.462 ms -1.3%
casing/bool/2000 35.02 μs 35.32 μs +0.9%
casing/bool/4000 72.62 μs 71.46 μs -1.6%
casing/bool/6000 108.3 μs 105.5 μs -2.6%
casing/bool/8000 143.5 μs 139.7 μs -2.6%
casing/bool/10000 179.4 μs 171.1 μs -4.6%
casing/bool/12000 213.9 μs 214.0 μs +0.0%
casing/bool 32.19 μs 33.29 μs +3.4%
casing/bool 63.73 μs 64.35 μs +1.0%
casing/bool 95.07 μs 98.44 μs +3.5%
casing/bool 126.6 μs 128.5 μs +1.5%
casing/bool 158.9 μs 163.5 μs +2.9%
casing/bool 191.0 μs 195.0 μs +2.1%
casing/integer/2000 40.87 μs 45.10 μs +10.3%
casing/integer/4000 80.62 μs 87.02 μs +7.9%
casing/integer/6000 122.2 μs 132.6 μs +8.5%
casing/integer/8000 159.6 μs 179.2 μs +12.3%
casing/integer/10000 191.7 μs 223.7 μs +16.7%
casing/integer/12000 239.9 μs 267.0 μs +11.3%
casing/list/2000 123.2 μs 126.5 μs +2.7%
casing/list/4000 281.9 μs 287.9 μs +2.1%
casing/list/6000 476.9 μs 483.5 μs +1.4%
casing/list/8000 701.5 μs 707.1 μs +0.8%
casing/list/10000 993.1 μs 997.3 μs +0.4%
casing/list/12000 1.364 ms 1.378 ms +1.0%
casing/list 122.6 μs 125.4 μs +2.3%
casing/list 278.2 μs 286.7 μs +3.1%
casing/list 472.6 μs 476.6 μs +0.8%
casing/list 697.0 μs 709.0 μs +1.7%
casing/list 978.2 μs 994.5 μs +1.7%
casing/list 1.342 ms 1.350 ms +0.6%
casing/regularApply/3 583.1 ns 602.4 ns +3.3%
casing/regularApply/10 689.0 ns 713.6 ns +3.6%
casing/regularApply/30 977.0 ns 996.0 ns +1.9%
casing/regularApply/100 2.159 μs 2.196 μs +1.7%
casing/regularApply/500 8.999 μs 8.958 μs -0.5%
casing/regularApply/1000 18.40 μs 18.43 μs +0.2%
casing/caseApply/3 626.7 ns 646.6 ns +3.2%
casing/caseApply/10 767.4 ns 796.2 ns +3.8%
casing/caseApply/30 1.118 μs 1.155 μs +3.3%
casing/caseApply/100 2.767 μs 2.829 μs +2.2%
casing/caseApply/500 11.79 μs 12.18 μs +3.3%
casing/caseApply/1000 23.91 μs 24.81 μs +3.8%
f424a79 894db47 Change
TOTAL 56.59 ms 56.06 ms -0.9%

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants