Skip to content

Commit

Permalink
Performance improvement for DecimalNumber.set_value
Browse files Browse the repository at this point in the history
  • Loading branch information
3b1b committed Feb 8, 2024
1 parent f3571cf commit 8417369
Showing 1 changed file with 31 additions and 24 deletions.
55 changes: 31 additions & 24 deletions manimlib/mobject/numbers.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from __future__ import annotations
from functools import lru_cache

import numpy as np

Expand All @@ -17,6 +18,11 @@
T = TypeVar("T", bound=VMobject)


@lru_cache()
def char_to_cahced_mob(char: str, **text_config):
return Text(char, **text_config)


class DecimalNumber(VMobject):
def __init__(
self,
Expand Down Expand Up @@ -46,7 +52,7 @@ def __init__(
self.edge_to_fix = edge_to_fix
self.font_size = font_size
self.text_config = dict(text_config)
self.char_to_mob_map = dict()
self.text_config["font_size"] = font_size

super().__init__(
color=color,
Expand All @@ -59,36 +65,41 @@ def __init__(
self.init_colors()

def set_submobjects_from_number(self, number: float | complex) -> None:
# Create the submobject list
self.number = number
self.set_submobjects([])
self.text_config["font_size"] = self.get_font_size()
num_string = self.num_string = self.get_num_string(number)
self.add(*map(self.char_to_mob, num_string))
self.num_string = self.get_num_string(number)

# Add non-numerical bits
# Submob_templates will be a list of cached Tex and Text mobjects,
# with the intent of calling .copy or .become on them
submob_templates = list(map(self.char_to_mob, self.num_string))
if self.show_ellipsis:
dots = self.char_to_mob("...")
dots.arrange(RIGHT, buff=2 * dots[0].get_width())
self.add(dots)
submob_templates.append(dots)
if self.unit is not None:
self.unit_sign = Tex(self.unit, font_size=self.get_font_size())
self.add(self.unit_sign)
submob_templates.append(self.char_to_mob(self.unit))

self.arrange(
buff=self.digit_buff_per_font_unit * self.get_font_size(),
aligned_edge=DOWN
)
# Set internals
if len(submob_templates) == len(self.submobjects):
for sm, smt in zip(self.submobjects, submob_templates):
sm.become(smt)
else:
self.set_submobjects([smt.copy() for smt in submob_templates])

font_size = self.get_font_size()
digit_buff = self.digit_buff_per_font_unit * font_size
self.scale(font_size / self.text_config["font_size"])
self.arrange(RIGHT, buff=digit_buff, aligned_edge=DOWN)

# Handle alignment of parts that should be aligned
# to the bottom
for i, c in enumerate(num_string):
if c == "–" and len(num_string) > i + 1:
# Handle alignment of special characters
for i, c in enumerate(self.num_string):
if c == "–" and len(self.num_string) > i + 1:
self[i].align_to(self[i + 1], UP)
self[i].shift(self[i + 1].get_height() * DOWN / 2)
elif c == ",":
self[i].shift(self[i].get_height() * DOWN / 2)
if self.unit and self.unit.startswith("^"):
self.unit_sign.align_to(self, UP)
self[-1].align_to(self, UP)

if self.include_background_rectangle:
self.add_background_rectangle()
Expand All @@ -111,12 +122,8 @@ def get_num_string(self, number: float | complex) -> str:
num_string = num_string.replace("-", "–")
return num_string

def char_to_mob(self, char: str) -> Tex | Text:
if char not in self.char_to_mob_map:
self.char_to_mob_map[char] = Text(char, **self.text_config)
result = self.char_to_mob_map[char].copy()
result.scale(self.get_font_size() / result.font_size)
return result
def char_to_mob(self, char: str) -> Text:
return char_to_cahced_mob(char, **self.text_config)

def init_uniforms(self) -> None:
super().init_uniforms()
Expand Down

0 comments on commit 8417369

Please sign in to comment.