[Cython] nonecheck and as_none_safe_node method

Zaur Shibzukhov szport at gmail.com
Tue Mar 5 08:30:26 CET 2013

2013/3/5 Stefan Behnel <stefan_ml at behnel.de>

> Zaur Shibzukhov, 05.03.2013 07:21:
> > In ExprNodes.py there are several places where method `as_none_safe_node`
> > was applied in order to wrap a node by NoneCheckNode.
> > I think it would be resonable to apply that mostly only in cases when
> > noncheck=True.
> >
> > Here are possible changes in ExprNodes.py:
> >
> https://github.com/intellimath/cython/commit/bd041680b78067007ad6b9894a2f2c18514e397c
> I consider the nonecheck option a quirk. In many, many cases, it's not
> obvious to a user to what constructs it applies. For example, we use it to
> guard against crashes when we optimise code, e.g. by inlining parts of a
> C-API function, when iterating over builtins, etc. In most of these cases,
> it depends on more than one parameter if the optimised code will be applied
> (and thus no None check) or the fallback, which usually does its own
> complete set of safety checks. So it's one of those options that may work
> safely in all unit tests and then crash in production.
> Remember, most cases where we leave a None check in the code are not those
> where it's obvious that a variable cannot be None because it was just
> assigned a non-None value. Most cases are about function arguments, i.e.
> values that come from outside of the current function, and thus are not
> "obviously" correct even for the human reader or author of the code.
> Also, I'm yet to see a case where a None check really makes a difference in
> performance. Often enough, the C compiler will be able to move them out of
> loops or drop them completely because it already saw a None check against
> the same local variable earlier on. In those cases, it's just Cython not
> being smart enough to drop them itself, but without an impact on runtime
> performance. And even if the C compiler is not smart enough either, at
> least the branch prediction of the processor will strike in the relevant
> cases (i.e. inside of loops) and reduce the overhead to "pretty much zero".
> All of this makes em think that we should be very careful when we consider
> this option for the generated code.
 I agree that directive nonecheck=False is dangarous in general.

This change mainly affect builtin objects (lists, tuples, dicts, unicode)
and some situation in function/method calls.
And it assume that when you apply this directive you know what you are
doing and why.

Note that Cython now already set nonecheck=False (but boundcheck and
wraparound sets to True in Options.py) by default.
But now it not affect builtin types and some special cases.

May be the safer strategy is to set nonecheck=True by default and allow
locally to apply nonecheck(False) when developer believes that it is
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/cython-devel/attachments/20130305/8d0d76e8/attachment.html>

More information about the cython-devel mailing list