# How can I create a workflow for physical unit safety in Python?

I work for an engineering firm which builds most of our physics models in Excel with VBA. For myself and many other younger mechanical engineers in the company, this is not a good solution - we grew up with Python and Matlab and are more comfortable in those languages.

I've developed a script in Python to approximate the solutions to certain physics equations. I used a library called Pint to create each variable as an object containing both magnitude and a physical (e.g. foot, meter, kilogram) dimension. This let's me check that the correctness of my physics equations, which is extremely useful because a lot of physics errors can be caught by checking units. However, this leads to a lot of overhead (10x slowdown). As noted in a comment below, this is because Pint and similar libraries instantiate new objects every time an arithmetic calculation is performed.

Because myself and others will be frequently creating similar programs, I want want to create a process for ensuring that there are no unit errors in our programs (e.g., adding a [length] unit to a [time] unit, or failing to convert between Celsius and Kelvin). What approach can be used for this that do not incur excessive overhead?

• A lot of Python libraries are written in C (or languages that can be compiled to C) for performance reasons. I was just looking into how you can build a CPython lib with Rust the other day. You don't have stop using Python in order to use a more performant language. Feb 7 at 16:05
• I'm struggling to understand why you have a 5-10X slowdown for this. Can you explain why this creates so much overhead? Are you calculating these on every calculation? It seems like for a given calculation routine, you can determine the units once and then process many inputs. What am I missing? Feb 7 at 16:41
• Naively, could you use SI units for everything internally? That is, your unit-aware types all have a method "to_si" (or whatever), do your calculations and then you can present the solution in whatever units are requested? Is there a concern about precision? Feb 7 at 22:25
• I don't know exactly what is taking so long with this but it just seems like it shouldn't be that costly. If you could put together a simple working example that demonstrates the performance hit, that would make for a better question. Feb 8 at 15:02
• I agree with @JimmyJames - a working example is needed to properly answer the question. There have been many times when I thought some package was slowing my code down, but 9 out of 10 times it was due to me not understanding how to use the package properly. Feb 8 at 16:05

What you want is

• a way to create user defined types (one type per dimension in a certain unit), with only certain conversions allowed between specific pairs of types

• typesafety with almost no overhead.

Sorry to say this, but Python (specifically the standard CPython implementation) and Matlab are the wrong programming languages for this (*). For this kind of requirements, languages like C++ or Rust are way better suited, but even Java or C# would give you easily a huge performance advantage (mostly because most of the type checking overhead happens during the compilation stage and not at run time).

So what can you do if you don't want to move completely away from the Python ecosystem? Some ideas:

• try to use Cython

• check if the PyPy can be used in your environment

• check if it helps to implement your module in C (or a "compatible" language with similar properties)

Of course, all of these approaches have their drawbacks, too. You have to check for yourself if those are suitable for you.

(*) Disclaimer to the nitpickers: when I write "languages" here, I mean this in the sense "the most popular implementations of those programming languages", not in the sense of "an abstract mathematical construct".