Skip to content

Commit f8d1d80

Browse files
committed
stdlib: Avoid repeated iolist to binary in io_lib_pretty binary path
The ?IND macro called list_to_binary(Ind) on every line wrap in the binary pretty-printer loops (pp_tail_bin, pp_pairs_tail_bin, pp_fields_tail_bin, pp_binary_bin_ind). Since Ind is constant within each loop, this re-flattened the same iolist on every sibling element that wrapped to a new line. Fix by converting Ind to binary lazily only in the branch that actually wraps, then threading the binary through subsequent iterations. The ?IND macro now expects a binary argument directly.
1 parent 05648d0 commit f8d1d80

1 file changed

Lines changed: 42 additions & 31 deletions

File tree

lib/stdlib/src/io_lib_pretty.erl

Lines changed: 42 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -436,7 +436,7 @@ pp_binary(S, N, _N0, Ind) ->
436436
end.
437437

438438

439-
-define(IND(Spaces), (list_to_binary(Spaces))/binary).
439+
-define(IND(Spaces), Spaces/binary).
440440

441441
pp_bin({_S,Len,_,_} = If, Col, Ll, M, _TInd, _Ind, LD, NL, W, Pos, Acc)
442442
when Len < Ll - Col - LD, Len + W + LD =< M ->
@@ -489,29 +489,33 @@ pp_map_bin([], _Col, _Ll, _M, _TInd, _Ind, _LD, NL, _W, Pos, Acc) ->
489489
{<<Acc/binary, $}>>, NL, Pos+1}; % cannot happen
490490
pp_map_bin({dots, _, _, _}, _Col, _Ll, _M, _TInd, _Ind, _LD, NL, _W, Pos, Acc) ->
491491
{<<Acc/binary, "...}">>, NL, Pos+4}; % cannot happen
492-
pp_map_bin([P | Ps], Col, Ll, M, TInd, Ind, LD, NL0, W, Pos0, Acc) ->
493-
{PS, NL, Pos, PW} = pp_pair_bin(P, Col, Ll, M, TInd, Ind, last_depth(Ps, LD), NL0, W, Pos0, Acc),
494-
pp_pairs_tail_bin(Ps, Col, Col+PW, Ll, M, TInd, Ind, LD, NL, PW, Pos, PS).
492+
pp_map_bin([P | Ps], Col, Ll, M, TInd, Ind0, LD, NL0, W, Pos0, Acc) ->
493+
I = map_value_indent(TInd),
494+
Ind = iolist_to_binary(Ind0),
495+
ValInd = iolist_to_binary(indent(I, Ind)),
496+
{PS, NL, Pos, PW} = pp_pair_bin(P, Col, Ll, M, TInd, Ind, I, ValInd, last_depth(Ps, LD), NL0, W, Pos0, Acc),
497+
pp_pairs_tail_bin(Ps, Col, Col+PW, Ll, M, TInd, Ind, I, ValInd, LD, NL, PW, Pos, PS).
495498

496-
pp_pairs_tail_bin([], _Col0, _Col, _Ll, _M, _TInd, _Ind, _LD, NL, _W, Pos, Acc) ->
499+
pp_pairs_tail_bin([], _Col0, _Col, _Ll, _M, _TInd, _Ind, _I, _ValInd, _LD, NL, _W, Pos, Acc) ->
497500
{<<Acc/binary, $}>>, NL, Pos+1};
498-
pp_pairs_tail_bin({dots, _, _, _}, _Col0, _Col, _M, _Ll, _TInd, _Ind, _L, NL, _W, Pos, Acc) ->
501+
pp_pairs_tail_bin({dots, _, _, _}, _Col0, _Col, _M, _Ll, _TInd, _Ind, _I, _ValInd, _L, NL, _W, Pos, Acc) ->
499502
{<<Acc/binary, ",...}">>, NL, Pos+5};
500-
pp_pairs_tail_bin([{_, Len, _, _}=P | Ps], Col0, Col, Ll, M, TInd, Ind, LD, NL0, W, Pos, Acc) ->
503+
pp_pairs_tail_bin([{_, Len, _, _}=P | Ps], Col0, Col, Ll, M, TInd, Ind0, I, ValInd, LD, NL0, W, Pos, Acc) ->
501504
LD1 = last_depth(Ps, LD),
502505
ELen = 1+Len,
503506
if
504507
LD1 =:= 0, ELen+1 < Ll-Col, W+ELen+1 =< M, ?ATM_PAIR(P);
505508
LD1 > 0, ELen < Ll-Col-LD1, W+ELen+LD1 =< M, ?ATM_PAIR(P) ->
506-
pp_pairs_tail_bin(Ps, Col0, Col+ELen, Ll, M, TInd, Ind, LD, NL0, W+ELen, Pos+ELen,
509+
pp_pairs_tail_bin(Ps, Col0, Col+ELen, Ll, M, TInd, Ind0, I, ValInd, LD, NL0, W+ELen, Pos+ELen,
507510
write_bin(P, <<Acc/binary, $,>>));
508511
true ->
509-
{PS, NL, Pos1, PW} = pp_pair_bin(P, Col0, Ll, M, TInd, Ind, LD1, NL0+1, 0, Col0,
512+
Ind = iolist_to_binary(Ind0),
513+
{PS, NL, Pos1, PW} = pp_pair_bin(P, Col0, Ll, M, TInd, Ind, I, ValInd, LD1, NL0+1, 0, Col0,
510514
<<Acc/binary, $,, $\n, ?IND(Ind)>>),
511-
pp_pairs_tail_bin(Ps, Col0, Col0+PW, Ll, M, TInd, Ind, LD, NL, PW, Pos1, PS)
515+
pp_pairs_tail_bin(Ps, Col0, Col0+PW, Ll, M, TInd, Ind, I, ValInd, LD, NL, PW, Pos1, PS)
512516
end.
513517

514-
pp_pair_bin({_, Len, _, _}=Pair, Col, Ll, M, _TInd, _Ind, LD, NL, W, Pos, Acc)
518+
pp_pair_bin({_, Len, _, _}=Pair, Col, Ll, M, _TInd, _Ind, _I, _ValInd, LD, NL, W, Pos, Acc)
515519
when Len < Ll - Col - LD, Len+W+LD =< M ->
516520
{write_bin(Pair, Acc),
517521
NL,
@@ -522,12 +526,10 @@ pp_pair_bin({_, Len, _, _}=Pair, Col, Ll, M, _TInd, _Ind, LD, NL, W, Pos, Acc)
522526
true ->
523527
Ll % force nl
524528
end};
525-
pp_pair_bin({{map_pair, K, V}, _Len, _, _}, Col0, Ll, M, TInd, Ind0, LD, NL0, W, Pos0, Acc0) ->
526-
I = map_value_indent(TInd),
527-
Ind = indent(I, Ind0),
529+
pp_pair_bin({{map_pair, K, V}, _Len, _, _}, Col0, Ll, M, TInd, Ind0, I, ValInd, LD, NL0, W, Pos0, Acc0) ->
528530
{Acc1, NL1, _} = pp_bin(K, Col0, Ll, M, TInd, Ind0, LD, NL0, W, Pos0, Acc0),
529-
{Acc2, NL, Pos} = pp_bin(V, Col0+I, Ll, M, TInd, Ind, LD, NL1+1, 0, Col0+I,
530-
<<Acc1/binary, " =>\n", ?IND(Ind)>>),
531+
{Acc2, NL, Pos} = pp_bin(V, Col0+I, Ll, M, TInd, ValInd, LD, NL1+1, 0, Col0+I,
532+
<<Acc1/binary, " =>\n", ?IND(ValInd)>>),
531533
{Acc2, NL, Pos, Ll}.
532534

533535
pp_record_bin([], _Nlen, _Col, _Ll, _M, _TInd, _Ind, _LD, NL, _W, Pos, Acc) ->
@@ -536,7 +538,8 @@ pp_record_bin({dots, _, _, _}, _Nlen, _Col, _Ll, _M, _TInd, _Ind, _LD, NL, _W, P
536538
{<<Acc/binary, "...}">>, NL, Pos+4};
537539
pp_record_bin([F | Fs], Nlen, Col0, Ll, M, TInd, Ind0, LD, NL0, W0, Pos0, Acc) ->
538540
Nind = Nlen+1,
539-
{Col, Ind, S, W} = rec_indent(Nind, TInd, Col0, Ind0, W0),
541+
{Col, Ind, S0, W} = rec_indent(Nind, TInd, Col0, Ind0, W0),
542+
S = iolist_to_binary(S0),
540543
{Pos1, NL1} = if W == 0 -> {Col, NL0+1}; true -> {Pos0, NL0} end,
541544
{FS, NL, Pos, FW} = pp_field_bin(F, Col, Ll, M, TInd, Ind, last_depth(Fs, LD), NL1, W, Pos1,
542545
<<Acc/binary, ?IND(S)>>),
@@ -546,15 +549,16 @@ pp_fields_tail_bin([], _Col0, _Col, _Ll, _M, _TInd, _Ind, _LD, NL, _W, Pos, Acc)
546549
{<<Acc/binary, $}>>, NL, Pos+1};
547550
pp_fields_tail_bin({dots, _, _ ,_}, _Col0, _Col, _M, _Ll, _TInd, _Ind, _LD, NL, _W, Pos, Acc) ->
548551
{<<Acc/binary, ",...}">>, NL, Pos+5};
549-
pp_fields_tail_bin([{_, Len, _, _}=F | Fs], Col0, Col, Ll, M, TInd, Ind, LD, NL0, W, Pos0, Acc) ->
552+
pp_fields_tail_bin([{_, Len, _, _}=F | Fs], Col0, Col, Ll, M, TInd, Ind0, LD, NL0, W, Pos0, Acc) ->
550553
LD1 = last_depth(Fs, LD),
551554
ELen = 1+Len,
552555
if
553556
LD1 =:= 0, ELen+1 < Ll-Col, W+ELen+1 =< M, ?ATM_FLD(F);
554557
LD1 > 0, ELen < Ll-Col-LD1, W+ELen+LD1 =< M, ?ATM_FLD(F) ->
555-
pp_fields_tail_bin(Fs, Col0, Col+ELen, Ll, M, TInd, Ind, LD, NL0, W+ELen, Pos0+ELen,
558+
pp_fields_tail_bin(Fs, Col0, Col+ELen, Ll, M, TInd, Ind0, LD, NL0, W+ELen, Pos0+ELen,
556559
write_field_bin(F, <<Acc/binary, $,>>));
557560
true ->
561+
Ind = iolist_to_binary(Ind0),
558562
{FS, NL, Pos, FW} = pp_field_bin(F, Col0, Ll, M, TInd, Ind, LD1, NL0+1, 0, Col0,
559563
<<Acc/binary, $,, $\n, ?IND(Ind)>>),
560564
pp_fields_tail_bin(Fs, Col0, Col0+FW, Ll, M, TInd, Ind, LD, NL, FW, Pos, FS)
@@ -570,7 +574,8 @@ pp_field_bin({_, Len, _, _}=Fl, Col, Ll, M, _TInd, _Ind, LD, NL, W, Pos, Acc)
570574
true -> Ll % force nl
571575
end};
572576
pp_field_bin({{field, Name0, NameL, F},_,_, _}, Col0, Ll, M, TInd, Ind0, LD, NL0, W0, Pos0, Acc0) ->
573-
{Col, Ind, S, W} = rec_indent(NameL, TInd, Col0, Ind0, W0+NameL),
577+
{Col, Ind, S0, W} = rec_indent(NameL, TInd, Col0, Ind0, W0+NameL),
578+
S = iolist_to_binary(S0),
574579
Name = unicode:characters_to_binary(Name0),
575580
{Acc, NL, Pos} =
576581
case W of
@@ -591,15 +596,16 @@ pp_list_bin([E | Es], Col0, Ll, M, TInd, Ind, LD, S, C, NL0, W, Pos0, Acc) ->
591596

592597
pp_tail_bin([], _Col0, _Col, _Ll, _M, _TInd, _Ind, _LD, _S, C, NL, _W, Pos, Acc) ->
593598
{<<Acc/binary, C>>, NL, Pos+1};
594-
pp_tail_bin([{_, Len, _, _}=E | Es], Col0, Col, Ll, M, TInd, Ind, LD, S, C, NL0, W, Pos0, Acc) ->
599+
pp_tail_bin([{_, Len, _, _}=E | Es], Col0, Col, Ll, M, TInd, Ind0, LD, S, C, NL0, W, Pos0, Acc) ->
595600
LD1 = last_depth(Es, LD),
596601
ELen = 1+Len,
597602
if
598603
LD1 =:= 0, ELen+1 < Ll-Col, W+ELen+1 =< M, ?ATM(E);
599604
LD1 > 0, ELen < Ll-Col-LD1, W+ELen+LD1 =< M, ?ATM(E) ->
600-
pp_tail_bin(Es, Col0, Col+ELen, Ll, M, TInd, Ind, LD, S, C, NL0, W+ELen, Pos0+ELen,
605+
pp_tail_bin(Es, Col0, Col+ELen, Ll, M, TInd, Ind0, LD, S, C, NL0, W+ELen, Pos0+ELen,
601606
write_bin(E, <<Acc/binary, $,>>));
602607
true ->
608+
Ind = iolist_to_binary(Ind0),
603609
{ES, NL, Pos, WE} = pp_element_bin(E, Col0, Ll, M, TInd, Ind, LD1, NL0+1, 0, Col0,
604610
<<Acc/binary, $,, $\n, ?IND(Ind)>>),
605611
pp_tail_bin(Es, Col0, Col0+WE, Ll, M, TInd, Ind, LD, S, C, NL, WE, Pos, ES)
@@ -612,7 +618,8 @@ pp_tail_bin({_, Len, _, _}=E, _Col0, Col, Ll, M, _TInd, _Ind, LD, S, C, NL, W, P
612618
?ATM(E) ->
613619
Acc1 = write_bin(E, <<Acc/binary, S>>),
614620
{<<Acc1/binary, C>>, NL, Pos+1+Len};
615-
pp_tail_bin(E, Col0, _Col, Ll, M, TInd, Ind, LD, S, C, NL0, _W, _Pos0, Acc) ->
621+
pp_tail_bin(E, Col0, _Col, Ll, M, TInd, Ind0, LD, S, C, NL0, _W, _Pos0, Acc) ->
622+
Ind = iolist_to_binary(Ind0),
616623
{Acc1, NL, Pos} = pp_bin(E, Col0, Ll, M, TInd, Ind, LD+1, NL0+1, 0, Col0,
617624
<<Acc/binary, S, $\n, ?IND(Ind)>>),
618625
{<<Acc1/binary, C>>, NL, Pos+1}.
@@ -629,38 +636,41 @@ pp_binary_bin(Orig, Col, Ll, M, Ind, LD, NL, W, Pos, Acc) ->
629636
<<$<,$<,Rest/binary>> = Orig,
630637
pp_binary_bin_ind(Rest, Orig, Ind, 0, 2, N, N, NL, Pos, Acc).
631638

632-
pp_binary_bin_ind(<<_,$,, Rest/binary>>, Orig, Ind, S, I, N, N0, NL, Pos, Acc) ->
639+
pp_binary_bin_ind(<<_,$,, Rest/binary>>, Orig, Ind0, S, I, N, N0, NL, Pos, Acc) ->
633640
N1 = N-2,
634641
case N1 < 0 of
635642
false ->
636-
pp_binary_bin_ind(Rest, Orig, Ind, S, I+2, N1, N0, NL, Pos, Acc);
643+
pp_binary_bin_ind(Rest, Orig, Ind0, S, I+2, N1, N0, NL, Pos, Acc);
637644
true ->
638645
Part = binary:part(Orig, S, I),
646+
Ind = iolist_to_binary(Ind0),
639647
pp_binary_bin_ind(Rest, Orig, Ind, S+I, 2, N0-2, N0, NL+1, 0,
640648
<<Acc/binary, Part/binary, $\n, ?IND(Ind)>>)
641649
end;
642-
pp_binary_bin_ind(<<_,_,$,, Rest/binary>>, Orig, Ind, S, I, N, N0, NL, Pos, Acc) ->
650+
pp_binary_bin_ind(<<_,_,$,, Rest/binary>>, Orig, Ind0, S, I, N, N0, NL, Pos, Acc) ->
643651
N1 = N-3,
644652
case N1 < 0 of
645653
false ->
646-
pp_binary_bin_ind(Rest, Orig, Ind, S, I+3, N1, N0, NL, Pos, Acc);
654+
pp_binary_bin_ind(Rest, Orig, Ind0, S, I+3, N1, N0, NL, Pos, Acc);
647655
true ->
648656
Part = binary:part(Orig, S, I),
657+
Ind = iolist_to_binary(Ind0),
649658
pp_binary_bin_ind(Rest, Orig, Ind, S+I, 3, N0-3, N0, NL+1, Pos,
650659
<<Acc/binary, Part/binary, $\n, ?IND(Ind)>>)
651660
end;
652-
pp_binary_bin_ind(<<_,_,_,$,, Rest/binary>>, Orig, Ind, S, I, N, N0, NL, Pos, Acc) ->
661+
pp_binary_bin_ind(<<_,_,_,$,, Rest/binary>>, Orig, Ind0, S, I, N, N0, NL, Pos, Acc) ->
653662
N1 = N-4,
654663
case N1 < 0 of
655664
false ->
656-
pp_binary_bin_ind(Rest, Orig, Ind, S, I+4, N1, N0, NL, Pos, Acc);
665+
pp_binary_bin_ind(Rest, Orig, Ind0, S, I+4, N1, N0, NL, Pos, Acc);
657666
true ->
658667
Part = binary:part(Orig, S, I),
668+
Ind = iolist_to_binary(Ind0),
659669
pp_binary_bin_ind(Rest, Orig, Ind, S+I, 4, N0-4, N0, NL+1, Pos,
660670
<<Acc/binary, Part/binary, $\n, ?IND(Ind)>>)
661671
end;
662-
pp_binary_bin_ind(Bin, Orig, Ind, S, I, N, _, NL, Pos0, Acc) ->
663-
Col = iolist_size(Ind)+1,
672+
pp_binary_bin_ind(Bin, Orig, Ind0, S, I, N, _, NL, Pos0, Acc) ->
673+
Col = iolist_size(Ind0)+1,
664674
Pos = if Pos0 =:= 0 -> Col; true -> Pos0 end,
665675
case (byte_size(Bin)-2) > N of %% Don't count bin closing ">>"
666676
false when S =:= 0 ->
@@ -674,6 +684,7 @@ pp_binary_bin_ind(Bin, Orig, Ind, S, I, N, _, NL, Pos0, Acc) ->
674684
Part1 = binary:part(Orig, S, I),
675685
Sz = byte_size(Orig) - (S+I),
676686
Part2 = binary:part(Orig, S+I, Sz),
687+
Ind = iolist_to_binary(Ind0),
677688
{<<Acc/binary, Part1/binary, $\n, ?IND(Ind), Part2/binary>>,
678689
NL+1, Col+Sz}
679690
end.

0 commit comments

Comments
 (0)