"""PerfEvent class.
import os
import threading
from collections import namedtuple
from typing import Optional

# The span of time that the event ocurred.
Span = namedtuple("Span", "start_ns end_ns")

# What process/thread produced the event.
Origin = namedtuple("Origin", "process_id thread_id")

[docs]class PerfEvent: """A performance related event: timer, counter, etc. Parameters ---------- name : str The name of this event like "draw". start_ns : int Start time in nanoseconds. end_ns : int End time in nanoseconds. category :str Comma separated categories such has "render,update". process_id : int The process id that produced the event. thread_id : int The thread id that produced the event. phase : str The Chrome Tracing "phase" such as "X", "I", "C". **kwargs : dict Additional keyword arguments for the "args" field of the event. Attributes ---------- name : str The name of this event like "draw". span : Span The time span when the event happened. category : str Comma separated categories such has "render,update". origin : Origin The process and thread that produced the event. args : dict Arbitrary keyword arguments for this event. phase : str The Chrome Tracing phase (event type): "X" - Complete Events "I" - Instant Events "C" - Counter Events Notes ----- The time stamps are from perf_counter_ns() and do not indicate time of day. The origin is arbitrary, but subtracting two counters results in a valid span of wall clock time. If start is the same as the end the event was instant. Google the phrase "Trace Event Format" for the full Chrome Tracing spec. """ def __init__( self, name: str, start_ns: int, end_ns: int, category: Optional[str] = None, process_id: int = None, thread_id: int = None, phase: str = "X", # "X" is a "complete event" in their spec. **kwargs: dict, ): if process_id is None: process_id = os.getpid() if thread_id is None: thread_id = threading.get_ident() self.name: str = name self.span: Span = Span(start_ns, end_ns) self.category: str = category self.origin: Origin = Origin(process_id, thread_id) self.args = kwargs self.phase: str = phase
[docs] def update_end_ns(self, end_ns: int) -> None: """Update our end_ns with this new end_ns. Attributes ---------- end_ns : int The new ending time in nanoseconds. """ self.span = Span(self.span.start_ns, end_ns)
@property def start_us(self): """Start time in microseconds.""" return self.span.start_ns / 1e3 @property def start_ms(self): """Start time in milliseconds.""" return self.span.start_ns / 1e6 @property def duration_ns(self): """Duration in nanoseconds.""" return self.span.end_ns - self.span.start_ns @property def duration_us(self): """Duration in microseconds.""" return self.duration_ns / 1e3 @property def duration_ms(self): """Duration in milliseconds.""" return self.duration_ns / 1e6