mirror of
https://github.com/blakeblackshear/frigate.git
synced 2026-06-21 03:41:55 +03:00
perf(track): avoid per-frame allocations and list lookups in tracker
Two small per-object-per-frame improvements in the tracker hot path (match_and_update), both bit-identical: - get_stationary_threshold returned a freshly constructed StationaryThresholds (a dataclass plus a list) on every call for any label not in the three known lists - i.e. for common labels like person/dog. The default thresholds are constant and never mutated, so return a shared module-level singleton, as the other three cases already do. - untracked_object_boxes membership used `box not in [list of boxes]` (O(n)); build a set of box tuples for O(1) membership. Boxes are hashable as tuples and output is unchanged. get_stationary_threshold appeared in a live py-spy --gil profile of a camera process_frames worker. Adds tests for the threshold lookups. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
5003ab895c
commit
21c792c22b
39
frigate/test/test_stationary_classifier.py
Normal file
39
frigate/test/test_stationary_classifier.py
Normal file
@ -0,0 +1,39 @@
|
||||
"""Tests for stationary object classification thresholds."""
|
||||
|
||||
import unittest
|
||||
|
||||
from frigate.track.stationary_classifier import (
|
||||
DEFAULT_OBJECT_THRESHOLDS,
|
||||
DYNAMIC_OBJECT_THRESHOLDS,
|
||||
NON_STATIONARY_OBJECT_THRESHOLDS,
|
||||
STATIONARY_OBJECT_THRESHOLDS,
|
||||
StationaryThresholds,
|
||||
get_stationary_threshold,
|
||||
)
|
||||
|
||||
|
||||
class TestStationaryThresholds(unittest.TestCase):
|
||||
def test_known_labels_return_expected_singletons(self) -> None:
|
||||
self.assertIs(get_stationary_threshold("package"), STATIONARY_OBJECT_THRESHOLDS)
|
||||
self.assertIs(get_stationary_threshold("car"), DYNAMIC_OBJECT_THRESHOLDS)
|
||||
self.assertIs(
|
||||
get_stationary_threshold("license_plate"),
|
||||
NON_STATIONARY_OBJECT_THRESHOLDS,
|
||||
)
|
||||
|
||||
def test_unknown_label_returns_shared_default(self) -> None:
|
||||
# an unknown label must reuse the shared default instance, not allocate
|
||||
# a fresh one on every call (this runs per object per frame)
|
||||
first = get_stationary_threshold("person")
|
||||
second = get_stationary_threshold("dog")
|
||||
self.assertIs(first, DEFAULT_OBJECT_THRESHOLDS)
|
||||
self.assertIs(second, DEFAULT_OBJECT_THRESHOLDS)
|
||||
|
||||
def test_default_matches_a_fresh_instance(self) -> None:
|
||||
# the shared default must be value-equivalent to the previous
|
||||
# per-call StationaryThresholds()
|
||||
self.assertEqual(DEFAULT_OBJECT_THRESHOLDS, StationaryThresholds())
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
@ -641,9 +641,11 @@ class NorfairTracker(ObjectTracker):
|
||||
self.deregister(self.track_id_map[e_id], e_id)
|
||||
|
||||
# update list of object boxes that don't have a tracked object yet
|
||||
tracked_object_boxes = [obj["box"] for obj in self.tracked_objects.values()]
|
||||
tracked_object_boxes = {
|
||||
tuple(obj["box"]) for obj in self.tracked_objects.values()
|
||||
}
|
||||
self.untracked_object_boxes = [
|
||||
o[2] for o in detections if o[2] not in tracked_object_boxes
|
||||
o[2] for o in detections if tuple(o[2]) not in tracked_object_boxes
|
||||
]
|
||||
|
||||
def print_objects_as_table(self, tracked_objects: Sequence) -> None:
|
||||
|
||||
@ -63,6 +63,9 @@ NON_STATIONARY_OBJECT_THRESHOLDS = StationaryThresholds(
|
||||
max_stationary_history=4,
|
||||
)
|
||||
|
||||
# Default thresholds for any other object label
|
||||
DEFAULT_OBJECT_THRESHOLDS = StationaryThresholds()
|
||||
|
||||
|
||||
def get_stationary_threshold(label: str) -> StationaryThresholds:
|
||||
"""Get the stationary thresholds for a given object label."""
|
||||
@ -76,7 +79,7 @@ def get_stationary_threshold(label: str) -> StationaryThresholds:
|
||||
if label in NON_STATIONARY_OBJECT_THRESHOLDS.objects:
|
||||
return NON_STATIONARY_OBJECT_THRESHOLDS
|
||||
|
||||
return StationaryThresholds()
|
||||
return DEFAULT_OBJECT_THRESHOLDS
|
||||
|
||||
|
||||
class StationaryMotionClassifier:
|
||||
|
||||
Loading…
Reference in New Issue
Block a user