optimize horizontal and vertical (#2234)

* optimize horizontal and vertical

* generator to list expressions

* micro op

* another micro-optimization
This commit is contained in:
Will McGugan
2023-04-06 21:05:51 +01:00
committed by GitHub
parent 44367a7422
commit 2969abf241
6 changed files with 43 additions and 30 deletions

View File

@@ -44,12 +44,12 @@ def resolve(
from_float = Fraction.from_float
total_fraction = from_float(
sum(scalar.value for scalar, fraction in resolved if fraction is None)
sum([scalar.value for scalar, fraction in resolved if fraction is None])
)
if total_fraction:
total_gutter = gutter * (len(dimensions) - 1)
consumed = sum(fraction for _, fraction in resolved if fraction is not None)
consumed = sum([fraction for _, fraction in resolved if fraction is not None])
remaining = max(Fraction(0), Fraction(total - total_gutter) - consumed)
fraction_unit = Fraction(remaining, total_fraction)
resolved_fractions = [
@@ -118,23 +118,21 @@ def resolve_box_models(
]
if dimension == "width":
total_remaining = sum(
box_model.width for box_model in box_models if box_model is not None
)
total_remaining = sum([width for width, _, _ in filter(None, box_models)])
remaining_space = max(0, size.width - total_remaining - margin_width)
else:
total_remaining = sum(
box_model.height for box_model in box_models if box_model is not None
)
total_remaining = sum([height for _, height, _ in filter(None, box_models)])
remaining_space = max(0, size.height - total_remaining - margin_height)
fraction_unit = Fraction(
remaining_space,
int(
sum(
dimension.value
for dimension in dimensions
if dimension and dimension.is_fraction
[
dimension.value
for dimension in dimensions
if dimension and dimension.is_fraction
]
)
)
or 1,

View File

@@ -1,11 +1,15 @@
from __future__ import annotations
from fractions import Fraction
from typing import TYPE_CHECKING
from .._layout import ArrangeResult, Layout, WidgetPlacement
from .._resolve import resolve_box_models
from ..geometry import Region, Size
from ..widget import Widget
if TYPE_CHECKING:
from ..geometry import Spacing
from ..widget import Widget
class HorizontalLayout(Layout):
@@ -24,17 +28,22 @@ class HorizontalLayout(Layout):
parent_size = parent.outer_size
child_styles = [child.styles for child in children]
box_margins = [styles.margin for styles in child_styles]
box_margins: list[Spacing] = [styles.margin for styles in child_styles]
if box_margins:
resolve_margin = Size(
(
sum(
max(margin1.right, margin2.left)
sum(
[
max(margin1[1], margin2[3])
for margin1, margin2 in zip(box_margins, box_margins[1:])
)
+ (box_margins[0].left + box_margins[-1].right)
]
)
+ (box_margins[0].left + box_margins[-1].right),
max(
[
margin_top + margin_bottom
for margin_top, _, margin_bottom, _ in box_margins
]
),
max(margin.height for margin in box_margins),
)
else:
resolve_margin = Size(0, 0)

View File

@@ -8,6 +8,7 @@ from .._resolve import resolve_box_models
from ..geometry import Region, Size
if TYPE_CHECKING:
from ..geometry import Spacing
from ..widget import Widget
@@ -24,17 +25,22 @@ class VerticalLayout(Layout):
parent_size = parent.outer_size
child_styles = [child.styles for child in children]
box_margins = [styles.margin for styles in child_styles]
box_margins: list[Spacing] = [styles.margin for styles in child_styles]
if box_margins:
resolve_margin = Size(
max([margin.width for margin in box_margins]),
(
sum(
max(margin1.bottom, margin2.top)
for margin1, margin2 in zip(box_margins, box_margins[1:])
)
+ (box_margins[0].top + box_margins[-1].bottom)
max(
[
margin_right + margin_left
for _, margin_right, _, margin_left in box_margins
]
),
sum(
[
max(margin1[2], margin2[0])
for margin1, margin2 in zip(box_margins, box_margins[1:])
]
)
+ (box_margins[0].top + box_margins[-1].bottom),
)
else:
resolve_margin = Size(0, 0)

View File

@@ -25,7 +25,7 @@ def get_line_length(segments: Iterable[Segment]) -> int:
Length of line in cells.
"""
_cell_len = cell_len
return sum(_cell_len(text) for text, _, control in segments if not control)
return sum([_cell_len(text) for text, _, control in segments if not control])
class StripRenderable:

View File

@@ -1056,7 +1056,7 @@ class Widget(DOMNode):
options = self._console.options.update_width(width).update(highlight=False)
segments = self._console.render(renderable, options)
# Cheaper than counting the lines returned from render_lines!
height = sum(text.count("\n") for text, _, _ in segments)
height = sum([text.count("\n") for text, _, _ in segments])
self._content_height_cache = (cache_key, height)
return height

View File

@@ -155,7 +155,7 @@ class TextLog(ScrollView, can_focus=True):
self.max_width = max(
self.max_width,
max(sum(segment.cell_length for segment in _line) for _line in lines),
max(sum([segment.cell_length for segment in _line]) for _line in lines),
)
strips = Strip.from_lines(lines)
for strip in strips: