Skip to content

Commit 0828d08

Browse files
perf(viewer): reuse click handlers instead of rebuilding them per render
Six factories built a fresh closure for every dropdown option on every render and registered it in globals(). Mesop memoizes handler ids on the function object itself (compute_fn_id is an unbounded lru_cache), so a new closure per render meant a permanent entry per render: 300 renders of a 40-option dropdown added 12,000 entries instead of 40. Hoist the factories to module level and memoize them by value, so the same option yields the same function object and mesop's table stays flat. The globals() writes go with them; nothing ever read those names. Handler __name__ is load-bearing and stays: mesop derives identity from name plus source, and all handlers from one factory share source, so without it every option in a dropdown would dispatch to the same value. Names now carry a short digest of the raw value, since the old sanitizer mapped "a.b" and "a-b" to one name and silently merged them.
1 parent fef7b53 commit 0828d08

1 file changed

Lines changed: 42 additions & 67 deletions

File tree

viewer/main.py

Lines changed: 42 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
11
import os
2+
import re
3+
import hashlib
24
import mesop as me
35
import pandas as pd
46
import yaml
57
import logging
68
import json
79
import subprocess
10+
from functools import lru_cache
811
import precompute_trends
912
import dataset_quality
1013
from summarizer import summarize_eval_scoring
@@ -310,6 +313,39 @@ def on_load(e: me.LoadEvent):
310313
state.ai_comparison = compare_evals(eval1, eval2)
311314

312315

316+
def _handler_name(prefix, *parts):
317+
# Mesop identifies a handler by __name__ plus source, and every handler built by
318+
# one factory shares its source, so the name has to carry the values. The digest
319+
# keeps values that sanitize alike ("a.b" and "a-b") from sharing an identity.
320+
raw = "\x00".join(str(p) for p in parts)
321+
slug = re.sub(r"\W+", "_", raw.replace("\x00", "_"))
322+
return f"{prefix}_{slug}_{hashlib.sha1(raw.encode()).hexdigest()[:8]}"
323+
324+
325+
# Mesop memoizes on the handler object itself, so a fresh closure per render grows
326+
# its table forever. Returning the same object per value keeps that table bounded.
327+
@lru_cache(maxsize=4096)
328+
def _set_filter_handler(field, value):
329+
def handler(e: me.ClickEvent):
330+
st = me.state(State)
331+
setattr(st, field, value)
332+
st.open_dropdown = ""
333+
334+
handler.__name__ = _handler_name("set", field, value)
335+
return handler
336+
337+
338+
@lru_cache(maxsize=4096)
339+
def _status_row_handler(product, dataset):
340+
def handler(e: me.ClickEvent):
341+
st = me.state(State)
342+
st.selected_main_tab = "List"
343+
st.product_filter = product
344+
st.dataset_filter = dataset
345+
st.list_agent_tab = st.status_agent_tab
346+
347+
handler.__name__ = _handler_name("click_status_row", product, dataset)
348+
return handler
313349

314350

315351

@@ -526,22 +562,7 @@ def render_cell(text, color="#334155", cell_bg=None, on_click=None):
526562
product_val = str(row['Product'])
527563
dataset_val = str(row['Dataset'])
528564

529-
def make_click_handler(p_val, d_val, g_val):
530-
def handler(e: me.ClickEvent):
531-
st = me.state(State)
532-
st.selected_main_tab = "List"
533-
st.product_filter = p_val
534-
st.dataset_filter = d_val
535-
st.list_agent_tab = st.status_agent_tab
536-
537-
safe_p = str(p_val).replace(" ", "_").replace(".", "_").replace("-", "_")
538-
safe_d = str(d_val).replace(" ", "_").replace(".", "_").replace("-", "_")
539-
handler_name = f"click_status_row_{safe_p}_{safe_d}"
540-
handler.__name__ = handler_name
541-
globals()[handler_name] = handler
542-
return handler
543-
544-
click_handler = make_click_handler(product_val, dataset_val, row.get('model_config.generator'))
565+
click_handler = _status_row_handler(product_val, dataset_val)
545566
render_cell(product_val, color="#2563eb", on_click=click_handler)
546567
render_cell("N/A" if is_na else dataset_val, color="#2563eb", on_click=None if is_na else click_handler)
547568

@@ -904,15 +925,7 @@ def toggle_eval_id_dropdown(e: me.ClickEvent):
904925
st.open_dropdown = "eval_id"
905926

906927
def make_eval_id_handler(val):
907-
def handler(e: me.ClickEvent):
908-
st = me.state(State)
909-
st.eval_id_filter = val
910-
st.open_dropdown = ""
911-
912-
handler_name = f"click_eval_id_{val}"
913-
handler.__name__ = handler_name
914-
globals()[handler_name] = handler
915-
return handler
928+
return _set_filter_handler("eval_id_filter", val)
916929

917930
with me.box(
918931
style=me.Style(
@@ -1005,17 +1018,7 @@ def toggle_product_dropdown(e: me.ClickEvent):
10051018
st.open_dropdown = "product"
10061019

10071020
def make_prod_dropdown_handler(val):
1008-
def handler(e: me.ClickEvent):
1009-
st = me.state(State)
1010-
st.product_filter = val
1011-
st.open_dropdown = ""
1012-
1013-
# Sanitize name for Mesop event routing
1014-
safe_val = str(val).replace(" ", "_").replace(".", "_").replace("-", "_")
1015-
handler_name = f"click_prod_dd_{safe_val}"
1016-
handler.__name__ = handler_name
1017-
globals()[handler_name] = handler
1018-
return handler
1021+
return _set_filter_handler("product_filter", val)
10191022

10201023
mk_prod_dd = make_prod_dropdown_handler
10211024

@@ -1110,17 +1113,7 @@ def toggle_requester_dropdown(e: me.ClickEvent):
11101113
st.open_dropdown = "requester"
11111114

11121115
def make_req_dropdown_handler(val):
1113-
def handler(e: me.ClickEvent):
1114-
st = me.state(State)
1115-
st.requester_filter = val
1116-
st.open_dropdown = ""
1117-
1118-
# Sanitize name for Mesop event routing
1119-
safe_val = str(val).replace(" ", "_").replace(".", "_").replace("-", "_")
1120-
handler_name = f"click_req_dd_{safe_val}"
1121-
handler.__name__ = handler_name
1122-
globals()[handler_name] = handler
1123-
return handler
1116+
return _set_filter_handler("requester_filter", val)
11241117

11251118
mk_req_dd = make_req_dropdown_handler
11261119

@@ -1215,17 +1208,7 @@ def toggle_dataset_dropdown(e: me.ClickEvent):
12151208
st.open_dropdown = "dataset"
12161209

12171210
def make_dataset_dropdown_handler(val):
1218-
def handler(e: me.ClickEvent):
1219-
st = me.state(State)
1220-
st.dataset_filter = val
1221-
st.open_dropdown = ""
1222-
1223-
# Sanitize name for Mesop event routing
1224-
safe_val = str(val).replace(" ", "_").replace(".", "_").replace("-", "_")
1225-
handler_name = f"click_dataset_dd_{safe_val}"
1226-
handler.__name__ = handler_name
1227-
globals()[handler_name] = handler
1228-
return handler
1211+
return _set_filter_handler("dataset_filter", val)
12291212

12301213
mk_dataset_dd = make_dataset_dropdown_handler
12311214

@@ -1320,15 +1303,7 @@ def toggle_rows_dropdown(e: me.ClickEvent):
13201303
st.open_dropdown = "rows_to_show"
13211304

13221305
def make_rows_handler(val):
1323-
def handler(e: me.ClickEvent):
1324-
st = me.state(State)
1325-
st.rows_to_show = val
1326-
st.open_dropdown = ""
1327-
1328-
handler_name = f"click_rows_{val}"
1329-
handler.__name__ = handler_name
1330-
globals()[handler_name] = handler
1331-
return handler
1306+
return _set_filter_handler("rows_to_show", val)
13321307

13331308
with me.box(
13341309
style=me.Style(

0 commit comments

Comments
 (0)