Skip to main content

A discrete-event simulation engine for time-based process benchmarking

Project description

SimTime

SimTime is a Python library for discrete-event simulation, supporting flexible event scheduling, detailed event recording, and custom metric collection. It is designed for simulating time-based processes, both synchronous and asynchronous, with periodic, rate-based, declared, or measured duration events.


Features

  • Discrete-event simulation engine with customizable event queue and time advancement.
  • Flexible event scheduling: absolute time, after delay, periodic, rate-based, or with custom callbacks.
  • Support for synchronous and asynchronous (coroutine) event functions.
  • Detailed event recording: logs of timing, results, errors, and metadata.
  • Custom metric collection and management during simulation.
  • Export results: events and metrics exportable as CSV/JSON (pandas optional; stdlib fallback included).

Installation

pip install simtime

# Optional: enable pandas-based DataFrame export
pip install "simtime[pandas]"

Quick Start

from simtime import TimeSimulator, EventType, prepare_func

# Define an event function
def my_event():
    print("Event executed!")

# Prepare the function for simulation (required)
my_event = prepare_func(EventType.DECLARED_DURATION, my_event, value=10)

# Create the simulator
sim = TimeSimulator()

# Create and schedule the event at simulation time 10
event = sim.create_event("my_event", my_event)
sim.schedule(event, at=10)

# Run the simulation until time 20
sim.run(until_time=20)

Event Types and Scheduling

Declared Duration

The event's simulated duration is a fixed value set at preparation time.

def task():
    print("Task with declared duration")

task = prepare_func(EventType.DECLARED_DURATION, task, value=50)  # 50 ms simulated
event = sim.create_event("task", task)
sim.schedule(event, at=0)

Measured Duration

The event's simulated duration is scaled from its real wall-clock execution time.

def measured_task():
    # Real computation here
    pass

measured_task = prepare_func(EventType.MEASURED_DURATION, measured_task)
event = sim.create_event("measured", measured_task)
sim.schedule(event, at=0)

Periodic

The event is automatically rescheduled at a fixed interval.

def periodic_task():
    print("Periodic event")

periodic_task = prepare_func(EventType.PERIODIC, periodic_task, value={"every_ms": 5})
event = sim.create_event("periodic", periodic_task)
sim.schedule(event, at=0)
sim.run(until_time=20)  # fires at t=0, 5, 10, 15

Rate-Based

Events are generated at a statistical arrival rate using a chosen distribution.

def rate_task():
    print("Rate-based event")

rate_task = prepare_func(
    EventType.RATE_BASED,
    rate_task,
    value={"rate_per_ms": 0.1, "dist": "poisson", "max_events": 10}
)
event = sim.create_event("rate", rate_task)
sim.schedule(event, at=0)

Supported distributions: "poisson", "uniform", "normal", "constant".

Asynchronous Events

Async functions are supported for all event types.

import asyncio

async def async_task():
    await asyncio.sleep(0.01)
    return "done"

async_task = prepare_func(EventType.DECLARED_DURATION, async_task, value=10)
event = sim.create_event("async", async_task)
sim.schedule(event, at=0)

Event Recording and Metrics

Accessing Event Records

for record in sim.recorder.records:
    print(record)

# As a list of dicts (no pandas needed)
dicts = sim.recorder.to_dicts()

# As a pandas DataFrame (requires pandas)
df = sim.recorder.to_dataframe()

Exporting Events

sim.recorder.save_csv("events.csv")
sim.recorder.save_json("events.json")

Using the Metric Store

sim.metrics_store.add(
    category="performance",
    type="latency",
    name="request_latency",
    value=123,
    tags={"endpoint": "/api"}
)

# Filter by category
perf_metrics = sim.metrics_store.get_by_category("performance")

sim.metrics_store.save_csv("metrics.csv")
sim.metrics_store.save_json("metrics.json")

Temporary Metrics

Temporary metrics are keyed by id and can be updated or removed during simulation.

sim.metrics_store.add_temp("in_flight", 0)
record = sim.metrics_store.get_temp("in_flight")
print(record.value)
sim.metrics_store.remove_temp("in_flight")

API Reference

TimeSimulator

TimeSimulator(
    step_ms: int = 1,
    jump_to_next_event: bool = True,
    scale_real_to_sim: float = 1.0,
    seed: Optional[int] = None,
)
Method Description
now() -> int Current simulation time in ms.
pending_count() -> int Number of events waiting in the queue.
create_event(name, func, args, kwargs, metadata, callback_event) -> Event Create an event from a prepared function.
schedule(event, at=None, delay=None) -> Event Enqueue an event.
run(until_time=None, until_events=None, stop_condition=None) Run the simulation.
stop() Signal the simulation to stop after the current batch.
reset() Reset clock, queue, recorder, and metrics to initial state.
add_measured_time(function, value) Add extra simulated ms to a MEASURED_DURATION function.
recorder Recorder instance for event logs.
metrics_store MetricStore instance for metrics.

prepare_func

prepare_func(event_type: EventType, func, value=None) -> Callable

Prepares a function for simulation. Returns a copy; the original is not mutated.

Recorder

Method/Property Description
records List of EventRecord objects (copy).
to_dicts() -> list[dict] Records as plain dicts (no pandas needed).
to_dataframe() Records as pandas DataFrame. Requires pandas.
save_csv(path) Save to CSV (uses stdlib if pandas absent).
save_json(path) Save to JSON.

MetricStore

Method/Property Description
add(category, type, name, value, tags=None) Add a persistent metric.
get_by_category(category) -> list[MetricRecord] Filter metrics by category.
add_temp(id, value) Add/update a temporary metric.
get_temp(id) -> TempMetricRecord | None Retrieve a temporary metric.
remove_temp(id) Remove a temporary metric.
metrics All persistent MetricRecord objects (copy).
to_dicts() -> list[dict] Metrics as plain dicts.
to_dataframe() Metrics as pandas DataFrame. Requires pandas.
save_csv(path) Save to CSV.
save_json(path) Save to JSON.

Advanced Usage

  • Reproducible simulations: Pass seed=42 to TimeSimulator.
  • Step-by-step time advance: Set jump_to_next_event=False and configure step_ms.
  • Custom stop conditions: run(stop_condition=lambda sim: sim.now() >= 100).
  • Event chaining: Pass a callback_event to create_event; it fires after the parent completes.
  • Reset and rerun: Call sim.reset() between benchmark runs instead of creating a new instance.

Requirements

  • Python 3.9+
  • Optional: pandas>=1.3 for DataFrame export

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

simtime-0.2.0.tar.gz (17.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

simtime-0.2.0-py3-none-any.whl (12.7 kB view details)

Uploaded Python 3

File details

Details for the file simtime-0.2.0.tar.gz.

File metadata

  • Download URL: simtime-0.2.0.tar.gz
  • Upload date:
  • Size: 17.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.3

File hashes

Hashes for simtime-0.2.0.tar.gz
Algorithm Hash digest
SHA256 f681fb18c640d2c173ab40d0811e4b6c62ff9119feeeb6a3e55f3427a885182b
MD5 26cb12fef81481013acd8da9e9726d4c
BLAKE2b-256 cb6475af370a8a0362fc06ab28493fce9024dd64f8356e986355e0d54f1ee245

See more details on using hashes here.

File details

Details for the file simtime-0.2.0-py3-none-any.whl.

File metadata

  • Download URL: simtime-0.2.0-py3-none-any.whl
  • Upload date:
  • Size: 12.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.3

File hashes

Hashes for simtime-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 0daa0e2d2ff3b61b33b45769081cf597d2a243f9f59b55472f568c0355e0db85
MD5 41adccf167c776eee668e0945991dafa
BLAKE2b-256 99763a34de4f6b3371f5b27266e3c01c766d3ab4d1f3a8a40b1ba237100e31c2

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page