-module(size_comparison). -export([run/0]). run() -> application:ensure_all_started(gmserialization), code:add_path("asn1"), io:format("=== Size Comparison: Legacy RLP vs DER ===~n~n"), Compare = fun(Desc, LegacyBin, DerBin) -> L = byte_size(LegacyBin), D = byte_size(DerBin), Overhead = D - L, Pct = case L of 0 -> 0; _ -> round(Overhead * 100 / L) end, io:format("~s~n", [Desc]), io:format(" Legacy: ~p bytes ~w~n", [L, LegacyBin]), Show = binary:part(DerBin, 0, min(18, D)), io:format(" DER: ~p bytes ~w~n", [D, Show]), io:format(" Overhead: +~p bytes (~p%)~n~n", [Overhead, Pct]) end, %% Case 1: tag+vsn + small int + small binary T1 = [{foo,int},{bar,binary}], V1 = [{foo,1},{bar,<<2>>}], Leg1 = gmser_chain_objects:serialize(account, 1, T1, V1), DerVal1 = {'GajumaruData', 10, 1, {templateFields, [ {'TemplateField', <<"foo">>, {intValue, 1}}, {'TemplateField', <<"bar">>, {binaryValue, <<2>>}} ]}}, {ok, Der1} = 'GajumaruSerialization':encode('GajumaruData', DerVal1), Compare("Case 1: tag+vsn + small int + tiny binary (2 fields)", Leg1, Der1), %% Case 2: zero + empty binary V2 = [{foo,0},{bar,<<>>}], Leg2 = gmser_chain_objects:serialize(account, 1, T1, V2), DerVal2 = {'GajumaruData', 10, 1, {templateFields, [ {'TemplateField', <<"foo">>, {intValue, 0}}, {'TemplateField', <<"bar">>, {binaryValue, <<>>}} ]}}, {ok, Der2} = 'GajumaruSerialization':encode('GajumaruData', DerVal2), Compare("Case 2: zero int + empty binary", Leg2, Der2), %% Case 3: list of ints T3 = [{xs,[int]}], V3 = [{xs,[1,2,3]}], Leg3 = gmser_chain_objects:serialize(account, 1, T3, V3), DerVal3 = {'GajumaruData', 10, 1, {templateFields, [ {'TemplateField', <<"xs">>, {listValue, [ {intValue,1},{intValue,2},{intValue,3} ]}} ]}}, {ok, Der3} = 'GajumaruSerialization':encode('GajumaruData', DerVal3), Compare("Case 3: list of 3 small ints", Leg3, Der3), %% Case 4: tuple (int, binary) T4 = [{p,{int,binary}}], V4 = [{p,{42,<<"hi">>}}], Leg4 = gmser_chain_objects:serialize(account, 1, T4, V4), DerVal4 = {'GajumaruData', 10, 1, {templateFields, [ {'TemplateField', <<"p">>, {tupleValue, [ {intValue,42}, {binaryValue,<<"hi">>} ]}} ]}}, {ok, Der4} = 'GajumaruSerialization':encode('GajumaruData', DerVal4), Compare("Case 4: fixed tuple (int + 2-byte binary)", Leg4, Der4), %% Case 5: 256-byte payload Bin5 = crypto:strong_rand_bytes(256), T5 = [{data,binary}], V5 = [{data,Bin5}], Leg5 = gmser_chain_objects:serialize(account, 1, T5, V5), DerVal5 = {'GajumaruData', 10, 1, {templateFields, [ {'TemplateField', <<"data">>, {binaryValue, Bin5}} ]}}, {ok, Der5} = 'GajumaruSerialization':encode('GajumaruData', DerVal5), Compare("Case 5: 256-byte binary payload only", Leg5, Der5), %% Case 6: Concrete SignedTx style (no field names in DER) T6 = [{signatures,[binary]},{tx,binary}], V6 = [{signatures,[<<"sig1">>,<<"sig2">>]},{tx,<<"txbody123">>}], Leg6 = gmser_chain_objects:serialize(signed_tx, 1, T6, V6), DerVal6 = {'GajumaruData', 11, 1, {signedTx, {'SignedTx', [<<"sig1">>, <<"sig2">>], <<"txbody123">>}}}, {ok, Der6} = 'GajumaruSerialization':encode('GajumaruData', DerVal6), Compare("Case 6: SignedTx-like (concrete DER, no names)", Leg6, Der6), %% Case 7: 33-byte id-like value IdBin = <<1, 0:256>>, T7 = [{owner,binary}], V7 = [{owner,IdBin}], Leg7 = gmser_chain_objects:serialize(account, 1, T7, V7), DerVal7 = {'GajumaruData', 10, 1, {templateFields, [ {'TemplateField', <<"owner">>, {binaryValue, IdBin}} ]}}, {ok, Der7} = 'GajumaruSerialization':encode('GajumaruData', DerVal7), Compare("Case 7: 33-byte value (id-like)", Leg7, Der7), %% Case 8: Deeper nesting / more fields T8 = [{a,int},{b,binary},{c,[int]},{d,{int,int}}], V8 = [{a,123456},{b,<<"abcdef">>},{c,[10,20,30]},{d,{7,8}}], Leg8 = gmser_chain_objects:serialize(account, 1, T8, V8), DerVal8 = {'GajumaruData', 10, 1, {templateFields, [ {'TemplateField', <<"a">>, {intValue, 123456}}, {'TemplateField', <<"b">>, {binaryValue, <<"abcdef">>}}, {'TemplateField', <<"c">>, {listValue, [{intValue,10},{intValue,20},{intValue,30}]}}, {'TemplateField', <<"d">>, {tupleValue, [{intValue,7},{intValue,8}]}} ]}}, {ok, Der8} = 'GajumaruSerialization':encode('GajumaruData', DerVal8), Compare("Case 8: 4 fields mixed (int, bin, list, tuple)", Leg8, Der8), io:format("=== Analysis ===~n"), io:format("Note: Generic templateFields path includes IA5String field names.~n"), io:format("Concrete types (e.g. SignedTx) avoid name overhead.~n"), ok.