Skip to content

Commit

Permalink
faster pretty
Browse files Browse the repository at this point in the history
  • Loading branch information
willmcgugan committed Aug 10, 2020
1 parent f29fdf5 commit b7e66ce
Show file tree
Hide file tree
Showing 6 changed files with 45 additions and 15 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [5.1.2] - 2020-08-10

### Fixed

- Further optimized pretty printing ~5X.

## [5.1.1] - 2020-08-09

### Fixed
Expand Down
1 change: 1 addition & 0 deletions rich/cells.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ def cell_len(text: str, _cache: Dict[str, int] = LRUCache(1024 * 4)) -> int:
cached_result = _cache.get(text, None)
if cached_result is not None:
return cached_result

_get_size = get_character_cell_size
total_size = sum(_get_size(character) for character in text)
if len(text) <= 64:
Expand Down
22 changes: 11 additions & 11 deletions rich/pretty.py
Original file line number Diff line number Diff line change
Expand Up @@ -103,20 +103,18 @@ class _Line:

parts: List[str] = field(default_factory=list)
_cell_len: int = 0
_space: bool = False

def append(self, text: str) -> None:
"""Add text to line."""
# Efficiently keep track of cell length
self.parts.append(text)
self._cell_len += cell_len(text)
self._space = text.endswith(" ")

@property
def cell_len(self) -> int:
return (
self._cell_len
if self.parts and not self.parts[-1].endswith(" ")
else self._cell_len - 1
)
return self._cell_len - 1 if self._space else self._cell_len

@property
def text(self) -> str:
Expand Down Expand Up @@ -176,18 +174,21 @@ def to_repr_text(node: Any) -> str:

def traverse(node: Any, level: int = 0) -> None:
"""Walk the data structure."""

nonlocal line_break
append_line = lines.append

def append_text(text: str) -> None:
nonlocal max_width
nonlocal line_break
line = lines[-1]
line.append(text)
if max_width is not None and line.cell_len > max_width:
if line_break is not None and len(lines) <= line_break:
return
line_break = len(lines)
raise MaxLineReached(level)
max_width = None
else:
line_break = len(lines)
raise MaxLineReached(level)

node_id = id(node)
if node_id in visited_set:
Expand All @@ -209,8 +210,7 @@ def append_text(text: str) -> None:
if expanded:
append_line(_Line())
append_text(indent * (level + 1))
append_text(to_repr_text(key))
append_text(": ")
append_text(f"{to_repr_text(key)}: ")
traverse(value, level + 1)
if not last:
append_text(", ")
Expand All @@ -223,7 +223,7 @@ def append_text(text: str) -> None:
if not last:
append_text(", ")
if expanded:
lines.append(_Line())
append_line(_Line())
append_text(f"{indent * level}{brace_close}")
else:
append_text(brace_close)
Expand Down
1 change: 1 addition & 0 deletions tools/cats.json

Large diffs are not rendered by default.

22 changes: 22 additions & 0 deletions tools/profile_pretty.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import json
import io
from time import time
from rich.console import Console
from rich.pretty import Pretty



console = Console(file=io.StringIO(), color_system="truecolor", width=100)

with open("cats.json") as fh:
cats = json.load(fh)


start = time()
pretty = Pretty(cats)
console.print(pretty)
taken = (time() - start) * 1000


print(console.file.getvalue())
print(f"{taken:.1f}")
8 changes: 4 additions & 4 deletions tools/stress_test_pretty.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
from rich.console import Console
from rich.panel import Panel
from rich.pretty import Pretty

DATA = {
"foo": [1, 2, 3, (1, 2, 3), {4, 5, 6, (7, 8, 9)}, "Hello, World"],
"bar": [None, False, True],
"bar": [None, (False, True)] * 2,
}

console = Console()
for w in range(100):
console.print(DATA, width=w)
for w in range(130):
console.print(Panel(Pretty(DATA), width=w))

0 comments on commit b7e66ce

Please sign in to comment.