<div class="gmail_quote">On Tue, Mar 24, 2009 at 7:30 AM, Daniel Stutzbach <span dir="ltr">&lt;<a href="mailto:daniel@stutzbachenterprises.com" target="_blank">daniel@stutzbachenterprises.com</a>&gt;</span> wrote:<br><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">

<div><div class="gmail_quote">On Tue, Mar 24, 2009 at 4:30 AM, Hrvoje Niksic <span dir="ltr">&lt;<a href="mailto:hrvoje.niksic@avl.com" target="_blank">hrvoje.niksic@avl.com</a>&gt;</span> wrote:<br><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">


Agreed, and more importantly, I have yet to be convinced that those NULL checks introduce a measurable slowdown.  Daniel, have you tried measuring the performance difference with only the NULL checks removed?</blockquote>


</div><br></div>I&#39;ll play around with different permutations and report back on their impact.</blockquote></div><br>After playing around with it, I see that I was barking up the wrong tree.  That&#39;s what I get for tracing through code visually instead of using a debugger.<br>

<br>PyList implements tp_as_mapping, so it&#39;s mp_subscript method is called and the PySequence line is never used.  I tried many variations of special casing at various points in the path and removing extra checks.<br>

<br>It looks like function calls are the biggest expense.  Calls to functions within the same module appear to be cheap (presumably because gcc inlines them).<br><br>100 nanoseconds, py3k trunk:<br>ceval -&gt; PyObject_GetItem (object.c) -&gt; list_subscript (listobject.c) -&gt; PyNumber_AsSsize_t (object.c) -&gt; PyLong_AsSsize_t (longobject.c)<br>

<br>86 nanoseconds, by special-casing PyLong in list_subscript<br>ceval -&gt; PyObject_GetItem (object.c) -&gt;
list_subscript (listobject.c) -&gt; PyLong_AsSsize_t (longobject.c)<br>cost: could slow down mylist[some_PyNumber_that_is_not_a_long_yet_still_a_valid_index] (who cares?)<br><br>75 nanoseconds, by special-casing PyList and PyLong in PyObject and using PyList_GET_ITEM<br>
ceval -&gt; PyObject_GetItem (object.c) -&gt; PyLong_AsSsize_t (longobject.c)<br>cost: could slow down not_a_list[x]<br>
<br>75 nanoseconds, by special-casing PyList and PyLong in ceval and using PyList_GET_ITEM<br>
ceval -&gt; PyLong_AsSsize_t (longobject.c)<br>cost: could slow down not_a_list[x]<br><br><br><br>I had been hoping to find something general to speed up all uses of __getitem__, but that doesn&#39;t seem possible.  Oh well. :-(<br>

<br><blockquote style="margin: 1.5em 0pt;">--<br>
Daniel Stutzbach, Ph.D.<br>
President, <a href="http://stutzbachenterprises.com">Stutzbach Enterprises, LLC</a>
</blockquote>