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.1.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.1-py3-none-any.whl (12.7 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: simtime-0.2.1.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.1.tar.gz
Algorithm Hash digest
SHA256 cb48d7fafc08042f42c08d898d55245298b8b8705bc10f8b7c64fb144293dee8
MD5 4a0cc83b9751d77b0bef52bf45c44b79
BLAKE2b-256 2f1848da9a224e017c6ca4488013fd9bd1470753486d6395c98268d488ded6c6

See more details on using hashes here.

File details

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

File metadata

  • Download URL: simtime-0.2.1-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.1-py3-none-any.whl
Algorithm Hash digest
SHA256 ca24e9ecf8c9d4e4b989a9a874ca8eb9c7690c6c6bc6eb416e129ed433ce87ef
MD5 0246034d56006b407e1a502850456667
BLAKE2b-256 42cd9c6a26cb14bd777d6a681d62df6238cb86e01d775a56cff76b7cf37426b3

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