Chapter 10: Feature Comparison¶
10.1 DSSim vs Other DES Frameworks¶
The table below compares DSSim's own API with SimPy and salabim on key dimensions.
| Feature | DSSim (PubSubLayer2) | DSSim (LiteLayer2) | SimPy 4 | salabim |
|---|---|---|---|---|
| Process model | Generator / coroutine | Generator / coroutine | Generator | Generator |
| Spurious wakeups | None (condition filtering) | Possible (no condition gate) | Possible — when waiting for external state (e.g. credits & link-up), process must poll in a loop; events carry no predicate | Possible — process wakes on activate() and must re-check condition manually |
| Event type | Any Python object | Any Python object | Event object |
Internal |
| Publisher-subscriber | Yes (routing-rich, 4-phase) | Yes (fan-out only) | No | No |
| Delivery tiers / condition filtering | Yes (4-phase tiers + conditions) | No | No | No |
| Circuit conditions | Yes (AND/OR) | No | AnyOf/AllOf |
No |
| Arbitrary predicate conditions (lambdas) | Yes — any callable inspecting any simulation state | No | No — conditions are event objects, not predicates | No |
| Resource: variable-amount get / put | Yes — DSResource gget_n(n) / gput_n(n), integer or float amounts |
Yes — DSLiteResource, same API |
No — Container supports float amounts but has a different API; Resource is 1-unit only with no general get-n/put-n |
Yes — Resource.request(quantity=n) |
| Resource: unit-only optimized variant | Yes — DSUnitResource; no per-request _Waiter allocation, optimized dispatch loop |
Yes — DSLiteUnitResource; same + further reduced dispatch overhead |
Yes — Resource is inherently 1-unit and optimized for that case |
No dedicated unit-only variant |
| Priority queues | Yes | Yes | Yes | Yes |
| Preemption | Yes | Yes | Yes | Yes |
| No stdlib deps | Yes | Yes | Yes | Yes (Tkinter optional) |
| asyncio interop | Yes (shim) | No | No | No |
| Point-to-point event delivery | Yes — sim.send_object() (sync), sim.signal() (now), sim.schedule_event() (future) |
Yes — same three primitives | Partial — event.succeed(value) delivers to a waiting process; tied to event-object model |
Partial — component.activate() wakes a process; no payload |
| Interruptible processes | Yes — process.abort() |
Yes — process.abort() |
Yes — process.interrupt() |
Yes — component.activate() |
| Interruptible context handling | Yes — sim.interruptible(cond) context manager; condition-gated, structured |
No | No — process.interrupt() raises an exception directly on the process; not a context, no condition gate |
No |
| Probes / statistics | Yes — built-in and custom probe types | No | No | Yes — built-in only, no custom probe types |
| Timeout on every wait | Yes | Yes | Via Event |
Yes |
10.2 Key Takeaways¶
- DSSim PubSubLayer2 is the most feature-rich profile: condition filtering eliminates spurious wakeups, and the 4-phase pubsub system has no equivalent in SimPy or salabim.
- Both DSSim profiles accept any Python object as an event — no wrapping or base class required.
Noneis the universal timeout sentinel across all blocking APIs. - LiteLayer2 is closer to SimPy in scope, trading routing features for throughput. Both DSSim profiles support interruptible processes (
process.abort()); structured interruptible context handling (sim.interruptible(cond)) is PubSubLayer2-only. SimPy supports process interruption imperatively but has no structured context equivalent. - All profiles share the same timeout-everywhere convention; SimPy requires explicit
Eventwiring for equivalent behavior. - For migration paths from SimPy or salabim, see Chapter 9.