Re: C is it faster than numpy

Stestagg <[email protected]> Fri, 25 Feb 2022 10:37:45 +0000
Newsgroups gmane.comp.python.org.uk
Message-ID <CACFDE8YZUW2ZUEU+3FsRRjtdvP+0o36_1_Gh4ssm8FvLFNwrsg@mail.gmail.com>
--===============2900692946179592953==
Content-Type: multipart/alternative; boundary="00000000000053fbe605d8d54b25"

--00000000000053fbe605d8d54b25
Content-Type: text/plain; charset="UTF-8"

This is a fascinating subject. Firstly:

a lot of people think that C (or C++) is faster than python, yes I agree,
>

if you look at raw execution speed, then this is absolutely correct.  The
reasons for this are many and complex, but people who use this as a
standalone reason to avoid Python almost always don't actually understand
the subject too well.

If you want to read more about this, I would recommend searching for
"python glue language"  for example:

https://numpy.org/devdocs/user/c-info.python-as-glue.html


> *Is there another explanation ?*
>

Yes, the people who wrote numpy implemented sum() 'better' than you did.
That's not a put-down or anything, just an interesting reason why Python as
a glue language works so well. Lots of very smart people spend a lot of
time making numpy fast, because lots of people rely on it being fast
(partly because raw Python is a bit too slow to do these sorts of things
natively).

In C/C++ it's easy to say: 'it's just a for-loop, let's write it the simple
way'.   9 times out of 10, the for loop will be much faster than you ever
need it to be in either language, but if you really need speed for whatever
reason, you're going to have to reach for a library.  Numpy's popularity
means that everyone knows to just use it for this sort of thing
(interestingly, if you have a GPU, using something like pytorch might be
much faster here, depending on data transfer overheads).  In C/C++ there
are many many libraries that can do this sort of thing, but none have the
same general appeal as Numpy (in my opinion).

This means that with Python, you write the simple bits in a nice dynamic,
easy to write language, and the hard bits get farmed out to libraries like
numpy, and you benefit from some really awesome optimized code that make
your code faster than the naive equivalent 'fast' C implementation.

For example the following are all (i believe) different array sum
implementations for different CPU vector features across different
architectures/extensions:
https://github.com/numpy/numpy/blob/b97e7d585de4b80ae8202c1028c0dc03f5dde4ef/numpy/core/src/common/simd/avx512/arithmetic.h#L353
https://github.com/numpy/numpy/blob/b97e7d585de4b80ae8202c1028c0dc03f5dde4ef/numpy/core/src/common/simd/sse/arithmetic.h#L327
https://github.com/numpy/numpy/blob/b97e7d585de4b80ae8202c1028c0dc03f5dde4ef/numpy/core/src/common/simd/neon/arithmetic.h#L283

It's absolutely possible to make C/C++ perform at the same speed as numpy,
but you will have to invest a lot of time/effort in learning about
performance programming to get there (this can be a really useful skill to
learn, if you're interested!)

Some anecdotes:

1. I was using a C data logger library for some data logger device that
performed awfully, so I re-wrote it, feature-for-feature in python, and it
was 100x faster.  Why?  Not because Python is faster than C, just that
somewhere the original implementation had some bug/issue that was causing
slowness (It was related to sqlite transaction handling, but the C code
made it very hard to spot the issue, whereas the python was much easier to
reason about).  Nothing about what this library was doing required
high-performance code, so using Python was not a speed issue at all.

2. I worked on a very large data processing application for a fortune 500
co in Python, one part of the input pipeline was never going to be fast
enough for our volumes in pure python, so we wrote a custom module in
Cython (A hybrid language that compiles to a C/C++ extension), this small
module allowed the entire system to perform up to spec, and (along with a
numpy-like library) meant we could implement a lot of custom business logic
in Python, rather than in less expressive languages, and generally
out-perform similar Java/other language systems.


Steve

--00000000000053fbe605d8d54b25
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><div dir=3D"ltr">This is a fascinating subject. Firstly:<b=
r></div><br><div class=3D"gmail_quote"><blockquote class=3D"gmail_quote" st=
yle=3D"margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padd=
ing-left:1ex"><div dir=3D"ltr">a lot of people think that C (or C++) is fas=
ter than python, yes I agree, <br></div></blockquote><div><br></div><div>if=
 you look at raw execution speed, then this is absolutely correct.=C2=A0 Th=
e reasons for this are many and complex, but people who use this as a stand=
alone reason to avoid Python almost always don&#39;t actually understand th=
e subject too well.</div><div><br></div><div>If you want to read more about=
 this, I would recommend searching for &quot;python glue language&quot;=C2=
=A0 for example:</div><div><br></div><div><a href=3D"https://numpy.org/devd=
ocs/user/c-info.python-as-glue.html">https://numpy.org/devdocs/user/c-info.=
python-as-glue.html</a></div><div><br></div><blockquote class=3D"gmail_quot=
e" style=3D"margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204)=
;padding-left:1ex"><div dir=3D"ltr"><b>Is there another explanation ?<br></=
b></div></blockquote><div><br></div><div>Yes, the people who wrote numpy im=
plemented sum() &#39;better&#39; than you did.=C2=A0 That&#39;s not a put-d=
own or anything, just an interesting reason why Python as a glue language w=
orks so well. Lots of very smart people spend a lot of time making numpy fa=
st, because lots of people rely on it being fast (partly because raw Python=
 is a bit too slow to do these sorts of things natively).=C2=A0 <br></div><=
div><br></div><div>In C/C++ it&#39;s easy to say: &#39;it&#39;s just a for-=
loop, let&#39;s write it the simple way&#39;. =C2=A0 9 times out of 10, the=
 for loop will be much faster than you ever need it to be in either languag=
e, but if you really need speed for whatever reason, you&#39;re going to ha=
ve to reach for a library.=C2=A0 Numpy&#39;s popularity means that everyone=
 knows to just use it for this sort of thing (interestingly, if you have a =
GPU, using something like pytorch might be much faster here, depending on d=
ata transfer overheads).=C2=A0 In C/C++ there are many many libraries that =
can do this sort of thing, but none have the same general appeal as Numpy (=
in my opinion).<br></div><div><br></div><div>This means that with Python, y=
ou write the simple bits in a nice dynamic, easy to write language, and the=
 hard bits get farmed out to libraries like numpy, and you benefit from som=
e really awesome optimized code that make your code faster than the naive e=
quivalent &#39;fast&#39; C implementation.</div><div><br></div><div>For exa=
mple the following are all (i believe) different array sum implementations =
for different CPU vector features across different architectures/extensions=
:<br></div><div><a href=3D"https://github.com/numpy/numpy/blob/b97e7d585de4=
b80ae8202c1028c0dc03f5dde4ef/numpy/core/src/common/simd/avx512/arithmetic.h=
#L353">https://github.com/numpy/numpy/blob/b97e7d585de4b80ae8202c1028c0dc03=
f5dde4ef/numpy/core/src/common/simd/avx512/arithmetic.h#L353</a></div><div>=
<a href=3D"https://github.com/numpy/numpy/blob/b97e7d585de4b80ae8202c1028c0=
dc03f5dde4ef/numpy/core/src/common/simd/sse/arithmetic.h#L327">https://gith=
ub.com/numpy/numpy/blob/b97e7d585de4b80ae8202c1028c0dc03f5dde4ef/numpy/core=
/src/common/simd/sse/arithmetic.h#L327</a></div><div><a href=3D"https://git=
hub.com/numpy/numpy/blob/b97e7d585de4b80ae8202c1028c0dc03f5dde4ef/numpy/cor=
e/src/common/simd/neon/arithmetic.h#L283">https://github.com/numpy/numpy/bl=
ob/b97e7d585de4b80ae8202c1028c0dc03f5dde4ef/numpy/core/src/common/simd/neon=
/arithmetic.h#L283</a></div><div><br></div><div>It&#39;s absolutely possibl=
e to make C/C++ perform at the same speed as numpy, but you will have to in=
vest a lot of time/effort in learning about performance programming to get =
there (this can be a really useful skill to learn, if you&#39;re interested=
!)</div><div><br></div>Some anecdotes:</div><div class=3D"gmail_quote"><br>=
</div><div class=3D"gmail_quote">1. I was using a C data logger library for=
 some data logger device that performed awfully, so I re-wrote it, feature-=
for-feature in python, and it was 100x faster.=C2=A0 Why?=C2=A0 Not because=
 Python is faster than C, just that somewhere the original implementation h=
ad some bug/issue that was causing slowness (It was related to sqlite trans=
action handling, but the C code made it very hard to spot the issue, wherea=
s the python was much easier to reason about).=C2=A0 Nothing about what thi=
s library was doing required high-performance code, so using Python was not=
 a speed issue at all.</div><div class=3D"gmail_quote"><br></div><div class=
=3D"gmail_quote">2. I worked on a very large data processing application fo=
r a fortune 500 co in Python, one part of the input pipeline was never goin=
g to be fast enough for our volumes in pure python, so we wrote a custom mo=
dule in Cython (A hybrid language that compiles to a C/C++ extension), this=
 small module allowed the entire system to perform up to spec, and (along w=
ith a numpy-like library) meant we could implement a lot of custom business=
 logic in Python, rather than in less expressive languages, and generally o=
ut-perform similar Java/other language systems.</div><div class=3D"gmail_qu=
ote"><br></div><div class=3D"gmail_quote"><br></div><div class=3D"gmail_quo=
te">Steve</div><div class=3D"gmail_quote"><br></div><div class=3D"gmail_quo=
te"><br></div></div>

--00000000000053fbe605d8d54b25--

--===============2900692946179592953==
Content-Type: text/plain; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Content-Disposition: inline

_______________________________________________
python-uk mailing list
[email protected]
https://mail.python.org/mailman/listinfo/python-uk

--===============2900692946179592953==--