Usage Assertions and Performance¶
In order to help writing correct simulations, μSim uses a wide range of usage assertions. These generally verify argument values and types in advance, so that you can pinpoint where errors originate.
At the same time, μSim strives to provide best performance for correct simulations. Once you have verified your simulation, you can omit all consistency assertions with zero cost.
Note
μSim runs in assertion mode by default.
Assertions and Debug Extensions¶
μSim uses assertions when checking the internal logic of simulations. For example, time in a simulation must always advance into the future - assertions protect against creating events in the past.
>>> from usim import time, run
>>>
>>> async def wait(delay):
... await (time + delay)
...
>>> run(wait(-20)) # delay until a time that has already passed
When run regularly, this will fail with an AssertionError
.
The error includes some information to tell you what went wrong,
and attempts to explain how to fix it.
In addition to validating your simulation,
assertion mode also provides rich exception messages.
For example, erroneously using await time
provides
an Exception with additional help on intended usage.
Rich error messages in assertion mode
TypeError: 'time' cannot be used in 'await' expression
Use 'time' to derive operands for specific expressions:
* 'await (time + duration)' to delay for a specific duration
* 'await (time == date)' to proceed at a specific point in time
* 'await (time >= date)' to proceed at or after a point in time
* 'await (time < date)' to indefinitely block after a point in time
To get the current time, use 'time.now'
Reacting to Usage Errors¶
The purpose of assertions is to help simulation developers detect and remove inconsistencies and logic errors. They are not meant for the simulation itself to react to or even attempt recovery.
When an assertion of μSim fails, this means your simulation is in an undefined state. Instead of trying to recover, you should fix the root cause of the erroneous condition.
>>> try:
... risk.take_chance()
... except KeyError: # correct - recover from exception state
... risk.recover()
... except AssertionError: # incorrect - recover from corruption
... risk.recover()
Omitting Assertions¶
While assertions are important for verification, they incur a runtime performance overhead. If you trust your simulation to not need assertions, you can switch off all assertions to gain performance.
Starting Python with the -O
flag disables
μSim’s assertion mode.
Simulating in optimised mode
python3 -O my_simulation.py
In optimised mode, assertions are completely removed from μSim. There is no runtime overhead from checking debug mode versus optimised mode.
In addition to disabling assertions, rich exception messages are removed as well.
For example, erroneously using await time
provides
the regular Python error message.
Regular Python error messages in optimized mode
TypeError: object Time can't be used in 'await' expression
Notably, optimised mode throws the same exceptions as assertion mode
(except for AssertionError
).
Only the error message differs.