authorgravatar for 39384757+chwayne@users.noreply.github.comchwayne <39384757+chwayne@users.noreply.github.com> 2021-11-27 04:02:09+00:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2021-11-26 23:02:09-05:00
log755eeb7be0068f8a27aae1d5b8610c6c4da5162d
tree8898ae7b7cce932b66164250cb748358af98bde6
parentfdc04101f343ff090f0c54469a74dc960aa8d904
signaturebadge-question-mark Signed by PGP key 4AEE18F83AFDEB23

zig fmt: Fix performance issue with nested arrays (#10224)

* Remove double recursive call in renderArrayInit * Preserve an empty line before a comment line Fixes #10194

1 files changed, 36 insertions(+), 14 deletions(-)

lib/std/zig/render.zig+36-14
...@@ -1747,6 +1747,9 @@ fn renderArrayInit(...@@ -1747,6 +1747,9 @@ fn renderArrayInit(
1747 var sub_expr_buffer = std.ArrayList(u8).init(gpa);1747 var sub_expr_buffer = std.ArrayList(u8).init(gpa);
1748 defer sub_expr_buffer.deinit();1748 defer sub_expr_buffer.deinit();
17491749
1750 const sub_expr_buffer_starts = try gpa.alloc(usize, section_exprs.len + 1);
1751 defer gpa.free(sub_expr_buffer_starts);
1752
1750 var auto_indenting_stream = Ais{1753 var auto_indenting_stream = Ais{
1751 .indent_delta = indent_delta,1754 .indent_delta = indent_delta,
1752 .underlying_writer = sub_expr_buffer.writer(),1755 .underlying_writer = sub_expr_buffer.writer(),
...@@ -1757,11 +1760,13 @@ fn renderArrayInit(...@@ -1757,11 +1760,13 @@ fn renderArrayInit(
1757 var single_line = true;1760 var single_line = true;
1758 var contains_newline = false;1761 var contains_newline = false;
1759 for (section_exprs) |expr, i| {1762 for (section_exprs) |expr, i| {
1760 sub_expr_buffer.shrinkRetainingCapacity(0);1763 const start = sub_expr_buffer.items.len;
1764 sub_expr_buffer_starts[i] = start;
1765
1761 if (i + 1 < section_exprs.len) {1766 if (i + 1 < section_exprs.len) {
1762 try renderExpression(gpa, &auto_indenting_stream, tree, expr, .none);1767 try renderExpression(gpa, &auto_indenting_stream, tree, expr, .none);
1763 const width = sub_expr_buffer.items.len;1768 const width = sub_expr_buffer.items.len - start;
1764 const this_contains_newline = mem.indexOfScalar(u8, sub_expr_buffer.items, '\n') != null;1769 const this_contains_newline = mem.indexOfScalar(u8, sub_expr_buffer.items[start..], '\n') != null;
1765 contains_newline = contains_newline or this_contains_newline;1770 contains_newline = contains_newline or this_contains_newline;
1766 expr_widths[i] = width;1771 expr_widths[i] = width;
1767 expr_newlines[i] = this_contains_newline;1772 expr_newlines[i] = this_contains_newline;
...@@ -1779,9 +1784,10 @@ fn renderArrayInit(...@@ -1779,9 +1784,10 @@ fn renderArrayInit(
1779 column_counter = 0;1784 column_counter = 0;
1780 }1785 }
1781 } else {1786 } else {
1782 try renderExpression(gpa, &auto_indenting_stream, tree, expr, .none);1787 try renderExpression(gpa, &auto_indenting_stream, tree, expr, .comma);
1783 const width = sub_expr_buffer.items.len;1788 const width = sub_expr_buffer.items.len - start - 2;
1784 contains_newline = contains_newline or mem.indexOfScalar(u8, sub_expr_buffer.items, '\n') != null;1789 const this_contains_newline = mem.indexOfScalar(u8, sub_expr_buffer.items[start .. sub_expr_buffer.items.len - 1], '\n') != null;
1790 contains_newline = contains_newline or this_contains_newline;
1785 expr_widths[i] = width;1791 expr_widths[i] = width;
1786 expr_newlines[i] = contains_newline;1792 expr_newlines[i] = contains_newline;
17871793
...@@ -1789,21 +1795,38 @@ fn renderArrayInit(...@@ -1789,21 +1795,38 @@ fn renderArrayInit(
1789 const column = column_counter % row_size;1795 const column = column_counter % row_size;
1790 column_widths[column] = std.math.max(column_widths[column], width);1796 column_widths[column] = std.math.max(column_widths[column], width);
1791 }1797 }
1792 break;
1793 }1798 }
1794 }1799 }
1800 sub_expr_buffer_starts[section_exprs.len] = sub_expr_buffer.items.len;
17951801
1796 // Render exprs in current section.1802 // Render exprs in current section.
1797 column_counter = 0;1803 column_counter = 0;
1798 var last_col_index: usize = row_size - 1;
1799 for (section_exprs) |expr, i| {1804 for (section_exprs) |expr, i| {
1805 const start = sub_expr_buffer_starts[i];
1806 const end = sub_expr_buffer_starts[i + 1];
1807 const expr_text = sub_expr_buffer.items[start..end];
1808 if (!expr_newlines[i]) {
1809 try ais.writer().writeAll(expr_text);
1810 } else {
1811 var by_line = std.mem.split(u8, expr_text, "\n");
1812 var last_line_was_empty = false;
1813 try ais.writer().writeAll(by_line.next().?);
1814 while (by_line.next()) |line| {
1815 if (std.mem.startsWith(u8, line, "//") and last_line_was_empty) {
1816 try ais.insertNewline();
1817 } else {
1818 try ais.maybeInsertNewline();
1819 }
1820 last_line_was_empty = (line.len == 0);
1821 try ais.writer().writeAll(line);
1822 }
1823 }
1824
1800 if (i + 1 < section_exprs.len) {1825 if (i + 1 < section_exprs.len) {
1801 const next_expr = section_exprs[i + 1];1826 const next_expr = section_exprs[i + 1];
1802 try renderExpression(gpa, ais, tree, expr, .none);
1803
1804 const comma = tree.lastToken(expr) + 1;1827 const comma = tree.lastToken(expr) + 1;
18051828
1806 if (column_counter != last_col_index) {1829 if (column_counter != row_size - 1) {
1807 if (!expr_newlines[i] and !expr_newlines[i + 1]) {1830 if (!expr_newlines[i] and !expr_newlines[i + 1]) {
1808 // Neither the current or next expression is multiline1831 // Neither the current or next expression is multiline
1809 try renderToken(ais, tree, comma, .space); // ,1832 try renderToken(ais, tree, comma, .space); // ,
...@@ -1815,6 +1838,7 @@ fn renderArrayInit(...@@ -1815,6 +1838,7 @@ fn renderArrayInit(
1815 continue;1838 continue;
1816 }1839 }
1817 }1840 }
1841
1818 if (single_line and row_size != 1) {1842 if (single_line and row_size != 1) {
1819 try renderToken(ais, tree, comma, .space); // ,1843 try renderToken(ais, tree, comma, .space); // ,
1820 continue;1844 continue;
...@@ -1823,8 +1847,6 @@ fn renderArrayInit(...@@ -1823,8 +1847,6 @@ fn renderArrayInit(
1823 column_counter = 0;1847 column_counter = 0;
1824 try renderToken(ais, tree, comma, .newline); // ,1848 try renderToken(ais, tree, comma, .newline); // ,
1825 try renderExtraNewline(ais, tree, next_expr);1849 try renderExtraNewline(ais, tree, next_expr);
1826 } else {
1827 try renderExpression(gpa, ais, tree, expr, .comma); // ,
1828 }1850 }
1829 }1851 }
18301852
...@@ -2585,7 +2607,7 @@ fn nodeCausesSliceOpSpace(tag: Ast.Node.Tag) bool {...@@ -2585,7 +2607,7 @@ fn nodeCausesSliceOpSpace(tag: Ast.Node.Tag) bool {
2585 };2607 };
2586}2608}
25872609
2588// Returns the number of nodes in `expr` that are on the same line as `rtoken`.2610// Returns the number of nodes in `exprs` that are on the same line as `rtoken`.
2589fn rowSize(tree: Ast, exprs: []const Ast.Node.Index, rtoken: Ast.TokenIndex) usize {2611fn rowSize(tree: Ast, exprs: []const Ast.Node.Index, rtoken: Ast.TokenIndex) usize {
2590 const token_tags = tree.tokens.items(.tag);2612 const token_tags = tree.tokens.items(.tag);
25912613