Why is python's built in multiplication so fast [closed]












5















So the other day I was trying something in python, I was trying to write a custom multiplication function in python



def multi(x, y):
z = 0
while y > 0:
z = z + x
y = y - 1
return z


However, when I ran it with extremely large numbers like (1 << 90) and (1 << 45) which is (2 ^ 90) * (2 ^ 45). It took forever to compute.
So I tried looking into different types of multiplication, like the russian peasant multiplication technique, implemented down there, which was extremely fast but not as readable as multi(x, y)



def russian_peasant(x, y):
z = 0
while y > 0:
if y % 2 == 1: z = z + x
x = x << 1
y = y >> 1
return z


What I want you to answer is how do programming languages like python multiply numbers ?










share|improve this question















closed as too broad by jonrsharpe, Martijn Pieters, iCodez, SirGuy, rationalboss Feb 22 '14 at 22:23


Please edit the question to limit it to a specific problem with enough detail to identify an adequate answer. Avoid asking multiple distinct questions at once. See the How to Ask page for help clarifying this question. If this question can be reworded to fit the rules in the help center, please edit the question.























    5















    So the other day I was trying something in python, I was trying to write a custom multiplication function in python



    def multi(x, y):
    z = 0
    while y > 0:
    z = z + x
    y = y - 1
    return z


    However, when I ran it with extremely large numbers like (1 << 90) and (1 << 45) which is (2 ^ 90) * (2 ^ 45). It took forever to compute.
    So I tried looking into different types of multiplication, like the russian peasant multiplication technique, implemented down there, which was extremely fast but not as readable as multi(x, y)



    def russian_peasant(x, y):
    z = 0
    while y > 0:
    if y % 2 == 1: z = z + x
    x = x << 1
    y = y >> 1
    return z


    What I want you to answer is how do programming languages like python multiply numbers ?










    share|improve this question















    closed as too broad by jonrsharpe, Martijn Pieters, iCodez, SirGuy, rationalboss Feb 22 '14 at 22:23


    Please edit the question to limit it to a specific problem with enough detail to identify an adequate answer. Avoid asking multiple distinct questions at once. See the How to Ask page for help clarifying this question. If this question can be reworded to fit the rules in the help center, please edit the question.





















      5












      5








      5


      1






      So the other day I was trying something in python, I was trying to write a custom multiplication function in python



      def multi(x, y):
      z = 0
      while y > 0:
      z = z + x
      y = y - 1
      return z


      However, when I ran it with extremely large numbers like (1 << 90) and (1 << 45) which is (2 ^ 90) * (2 ^ 45). It took forever to compute.
      So I tried looking into different types of multiplication, like the russian peasant multiplication technique, implemented down there, which was extremely fast but not as readable as multi(x, y)



      def russian_peasant(x, y):
      z = 0
      while y > 0:
      if y % 2 == 1: z = z + x
      x = x << 1
      y = y >> 1
      return z


      What I want you to answer is how do programming languages like python multiply numbers ?










      share|improve this question
















      So the other day I was trying something in python, I was trying to write a custom multiplication function in python



      def multi(x, y):
      z = 0
      while y > 0:
      z = z + x
      y = y - 1
      return z


      However, when I ran it with extremely large numbers like (1 << 90) and (1 << 45) which is (2 ^ 90) * (2 ^ 45). It took forever to compute.
      So I tried looking into different types of multiplication, like the russian peasant multiplication technique, implemented down there, which was extremely fast but not as readable as multi(x, y)



      def russian_peasant(x, y):
      z = 0
      while y > 0:
      if y % 2 == 1: z = z + x
      x = x << 1
      y = y >> 1
      return z


      What I want you to answer is how do programming languages like python multiply numbers ?







      python algorithm






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited Feb 22 '14 at 17:09









      Games Brainiac

      42.9k25108157




      42.9k25108157










      asked Feb 22 '14 at 16:57









      rachit_vermarachit_verma

      9625




      9625




      closed as too broad by jonrsharpe, Martijn Pieters, iCodez, SirGuy, rationalboss Feb 22 '14 at 22:23


      Please edit the question to limit it to a specific problem with enough detail to identify an adequate answer. Avoid asking multiple distinct questions at once. See the How to Ask page for help clarifying this question. If this question can be reworded to fit the rules in the help center, please edit the question.









      closed as too broad by jonrsharpe, Martijn Pieters, iCodez, SirGuy, rationalboss Feb 22 '14 at 22:23


      Please edit the question to limit it to a specific problem with enough detail to identify an adequate answer. Avoid asking multiple distinct questions at once. See the How to Ask page for help clarifying this question. If this question can be reworded to fit the rules in the help center, please edit the question.


























          4 Answers
          4






          active

          oldest

          votes


















          9














          Your multi version runs in O(N) whereas russian_peasant version runs in O(logN), which is far better than O(N).



          To realize how fast your russian_peasant version is, check this out



          from math import log
          print round(log(100000000, 2)) # 27.0


          So, the loop has to be executed just 27 times, but your multi version's while loop has to be executed 100000000 times, when y is 100000000.



          To answer your other question,




          What I want you to answer is how do programming languages like python
          multiply numbers ?




          Python uses O(N^2) grade school multiplication algorithm for small numbers, but for big numbers it uses Karatsuba algorithm.



          Basically multiplication is handled in C code, which can be compiled to machine code and executed faster.






          share|improve this answer





















          • 1





            BTW, according to Wikipedia, Toom-Cook algorithm is faster than Karatsuba, and Schönhage–Strassen algorithm is even way faster than Toom-Cook. I'm just curious, anybody knows the reason behind choosing the Karatsuba algorithm in Python (for big numbers)?

            – oski86
            Jul 17 '15 at 22:40











          • @oski86 Those other algorithms essentially trade multiplications for some combination of adds, subs, shifts, and even constant divisions. Especially on modern processors, these algorithms only provide benefits at very high precision. On the Z80 and other older processors, the divisions that occur in other Toom-Cook algorithms render it less efficient than a clever implementation of Karatsuba, or even FFT/Schönhage–Strassen.

            – Zeda
            Jan 24 '18 at 19:00



















          4














          Programming languages like Python use the multiplication instruction provided by your computer's CPU.



          In addition, you have to remember that Python is a very high-level programming language, which runs on a virtual machine which itself runs on your computer. As such, it is, inherently, a few order of magnitudes slower than native code. Translating your algorithm to assembly (or even to C) would result in a massive speedup -- although it'd still be slower than the CPU's multiplication operation.



          On the plus side, unlike naive assembly/C, Python auto-promotes integers to bignums instead of overflowing when your numbers are bigger than 2**32.






          share|improve this answer































            3














            The basic answer to your question is this, multiplication using * is handled through C code. In essence if you write something in pure python its going to be slower than the C implementation, let me give you an example.



            The operator.mul function is implemented in C, but a lambda is implemented in Python, we're going to try to find the product of all the numbers in an array using functools.reduce and we are going to use two cases, one using operator.mul and another using a lambda which both do the same thing (on the surface):



            from timeit import timeit
            setup = """
            from functools import reduce
            from operator import mul
            """

            print(timeit('reduce(mul, range(1, 10))', setup=setup))
            print(timeit('reduce(lambda x, y: x * y, range(1, 10))', setup=setup))


            Output:



            1.48362842561
            2.67425475375


            operator.mul takes less time, as you can see.






            share|improve this answer































              0














              Usually, functional programming involving many computations is best made to take less time using memoization -- the basic idea is that if you feed a true function (something that always evaluates the same result for a given argument) the same thing twice or more, you're wasting time, time that could easily be saved by identifying common calls and storing whatever they evaluate down to into a hash table or other quickly-accessible object. See https://en.wikipedia.org/wiki/Memoization for basic theory. It is well-implemented in Common Lisp.






              share|improve this answer






























                4 Answers
                4






                active

                oldest

                votes








                4 Answers
                4






                active

                oldest

                votes









                active

                oldest

                votes






                active

                oldest

                votes









                9














                Your multi version runs in O(N) whereas russian_peasant version runs in O(logN), which is far better than O(N).



                To realize how fast your russian_peasant version is, check this out



                from math import log
                print round(log(100000000, 2)) # 27.0


                So, the loop has to be executed just 27 times, but your multi version's while loop has to be executed 100000000 times, when y is 100000000.



                To answer your other question,




                What I want you to answer is how do programming languages like python
                multiply numbers ?




                Python uses O(N^2) grade school multiplication algorithm for small numbers, but for big numbers it uses Karatsuba algorithm.



                Basically multiplication is handled in C code, which can be compiled to machine code and executed faster.






                share|improve this answer





















                • 1





                  BTW, according to Wikipedia, Toom-Cook algorithm is faster than Karatsuba, and Schönhage–Strassen algorithm is even way faster than Toom-Cook. I'm just curious, anybody knows the reason behind choosing the Karatsuba algorithm in Python (for big numbers)?

                  – oski86
                  Jul 17 '15 at 22:40











                • @oski86 Those other algorithms essentially trade multiplications for some combination of adds, subs, shifts, and even constant divisions. Especially on modern processors, these algorithms only provide benefits at very high precision. On the Z80 and other older processors, the divisions that occur in other Toom-Cook algorithms render it less efficient than a clever implementation of Karatsuba, or even FFT/Schönhage–Strassen.

                  – Zeda
                  Jan 24 '18 at 19:00
















                9














                Your multi version runs in O(N) whereas russian_peasant version runs in O(logN), which is far better than O(N).



                To realize how fast your russian_peasant version is, check this out



                from math import log
                print round(log(100000000, 2)) # 27.0


                So, the loop has to be executed just 27 times, but your multi version's while loop has to be executed 100000000 times, when y is 100000000.



                To answer your other question,




                What I want you to answer is how do programming languages like python
                multiply numbers ?




                Python uses O(N^2) grade school multiplication algorithm for small numbers, but for big numbers it uses Karatsuba algorithm.



                Basically multiplication is handled in C code, which can be compiled to machine code and executed faster.






                share|improve this answer





















                • 1





                  BTW, according to Wikipedia, Toom-Cook algorithm is faster than Karatsuba, and Schönhage–Strassen algorithm is even way faster than Toom-Cook. I'm just curious, anybody knows the reason behind choosing the Karatsuba algorithm in Python (for big numbers)?

                  – oski86
                  Jul 17 '15 at 22:40











                • @oski86 Those other algorithms essentially trade multiplications for some combination of adds, subs, shifts, and even constant divisions. Especially on modern processors, these algorithms only provide benefits at very high precision. On the Z80 and other older processors, the divisions that occur in other Toom-Cook algorithms render it less efficient than a clever implementation of Karatsuba, or even FFT/Schönhage–Strassen.

                  – Zeda
                  Jan 24 '18 at 19:00














                9












                9








                9







                Your multi version runs in O(N) whereas russian_peasant version runs in O(logN), which is far better than O(N).



                To realize how fast your russian_peasant version is, check this out



                from math import log
                print round(log(100000000, 2)) # 27.0


                So, the loop has to be executed just 27 times, but your multi version's while loop has to be executed 100000000 times, when y is 100000000.



                To answer your other question,




                What I want you to answer is how do programming languages like python
                multiply numbers ?




                Python uses O(N^2) grade school multiplication algorithm for small numbers, but for big numbers it uses Karatsuba algorithm.



                Basically multiplication is handled in C code, which can be compiled to machine code and executed faster.






                share|improve this answer















                Your multi version runs in O(N) whereas russian_peasant version runs in O(logN), which is far better than O(N).



                To realize how fast your russian_peasant version is, check this out



                from math import log
                print round(log(100000000, 2)) # 27.0


                So, the loop has to be executed just 27 times, but your multi version's while loop has to be executed 100000000 times, when y is 100000000.



                To answer your other question,




                What I want you to answer is how do programming languages like python
                multiply numbers ?




                Python uses O(N^2) grade school multiplication algorithm for small numbers, but for big numbers it uses Karatsuba algorithm.



                Basically multiplication is handled in C code, which can be compiled to machine code and executed faster.







                share|improve this answer














                share|improve this answer



                share|improve this answer








                edited Feb 22 '14 at 17:13

























                answered Feb 22 '14 at 17:05









                thefourtheyethefourtheye

                166k27297376




                166k27297376








                • 1





                  BTW, according to Wikipedia, Toom-Cook algorithm is faster than Karatsuba, and Schönhage–Strassen algorithm is even way faster than Toom-Cook. I'm just curious, anybody knows the reason behind choosing the Karatsuba algorithm in Python (for big numbers)?

                  – oski86
                  Jul 17 '15 at 22:40











                • @oski86 Those other algorithms essentially trade multiplications for some combination of adds, subs, shifts, and even constant divisions. Especially on modern processors, these algorithms only provide benefits at very high precision. On the Z80 and other older processors, the divisions that occur in other Toom-Cook algorithms render it less efficient than a clever implementation of Karatsuba, or even FFT/Schönhage–Strassen.

                  – Zeda
                  Jan 24 '18 at 19:00














                • 1





                  BTW, according to Wikipedia, Toom-Cook algorithm is faster than Karatsuba, and Schönhage–Strassen algorithm is even way faster than Toom-Cook. I'm just curious, anybody knows the reason behind choosing the Karatsuba algorithm in Python (for big numbers)?

                  – oski86
                  Jul 17 '15 at 22:40











                • @oski86 Those other algorithms essentially trade multiplications for some combination of adds, subs, shifts, and even constant divisions. Especially on modern processors, these algorithms only provide benefits at very high precision. On the Z80 and other older processors, the divisions that occur in other Toom-Cook algorithms render it less efficient than a clever implementation of Karatsuba, or even FFT/Schönhage–Strassen.

                  – Zeda
                  Jan 24 '18 at 19:00








                1




                1





                BTW, according to Wikipedia, Toom-Cook algorithm is faster than Karatsuba, and Schönhage–Strassen algorithm is even way faster than Toom-Cook. I'm just curious, anybody knows the reason behind choosing the Karatsuba algorithm in Python (for big numbers)?

                – oski86
                Jul 17 '15 at 22:40





                BTW, according to Wikipedia, Toom-Cook algorithm is faster than Karatsuba, and Schönhage–Strassen algorithm is even way faster than Toom-Cook. I'm just curious, anybody knows the reason behind choosing the Karatsuba algorithm in Python (for big numbers)?

                – oski86
                Jul 17 '15 at 22:40













                @oski86 Those other algorithms essentially trade multiplications for some combination of adds, subs, shifts, and even constant divisions. Especially on modern processors, these algorithms only provide benefits at very high precision. On the Z80 and other older processors, the divisions that occur in other Toom-Cook algorithms render it less efficient than a clever implementation of Karatsuba, or even FFT/Schönhage–Strassen.

                – Zeda
                Jan 24 '18 at 19:00





                @oski86 Those other algorithms essentially trade multiplications for some combination of adds, subs, shifts, and even constant divisions. Especially on modern processors, these algorithms only provide benefits at very high precision. On the Z80 and other older processors, the divisions that occur in other Toom-Cook algorithms render it less efficient than a clever implementation of Karatsuba, or even FFT/Schönhage–Strassen.

                – Zeda
                Jan 24 '18 at 19:00













                4














                Programming languages like Python use the multiplication instruction provided by your computer's CPU.



                In addition, you have to remember that Python is a very high-level programming language, which runs on a virtual machine which itself runs on your computer. As such, it is, inherently, a few order of magnitudes slower than native code. Translating your algorithm to assembly (or even to C) would result in a massive speedup -- although it'd still be slower than the CPU's multiplication operation.



                On the plus side, unlike naive assembly/C, Python auto-promotes integers to bignums instead of overflowing when your numbers are bigger than 2**32.






                share|improve this answer




























                  4














                  Programming languages like Python use the multiplication instruction provided by your computer's CPU.



                  In addition, you have to remember that Python is a very high-level programming language, which runs on a virtual machine which itself runs on your computer. As such, it is, inherently, a few order of magnitudes slower than native code. Translating your algorithm to assembly (or even to C) would result in a massive speedup -- although it'd still be slower than the CPU's multiplication operation.



                  On the plus side, unlike naive assembly/C, Python auto-promotes integers to bignums instead of overflowing when your numbers are bigger than 2**32.






                  share|improve this answer


























                    4












                    4








                    4







                    Programming languages like Python use the multiplication instruction provided by your computer's CPU.



                    In addition, you have to remember that Python is a very high-level programming language, which runs on a virtual machine which itself runs on your computer. As such, it is, inherently, a few order of magnitudes slower than native code. Translating your algorithm to assembly (or even to C) would result in a massive speedup -- although it'd still be slower than the CPU's multiplication operation.



                    On the plus side, unlike naive assembly/C, Python auto-promotes integers to bignums instead of overflowing when your numbers are bigger than 2**32.






                    share|improve this answer













                    Programming languages like Python use the multiplication instruction provided by your computer's CPU.



                    In addition, you have to remember that Python is a very high-level programming language, which runs on a virtual machine which itself runs on your computer. As such, it is, inherently, a few order of magnitudes slower than native code. Translating your algorithm to assembly (or even to C) would result in a massive speedup -- although it'd still be slower than the CPU's multiplication operation.



                    On the plus side, unlike naive assembly/C, Python auto-promotes integers to bignums instead of overflowing when your numbers are bigger than 2**32.







                    share|improve this answer












                    share|improve this answer



                    share|improve this answer










                    answered Feb 22 '14 at 17:03









                    Max NoelMax Noel

                    7,29511729




                    7,29511729























                        3














                        The basic answer to your question is this, multiplication using * is handled through C code. In essence if you write something in pure python its going to be slower than the C implementation, let me give you an example.



                        The operator.mul function is implemented in C, but a lambda is implemented in Python, we're going to try to find the product of all the numbers in an array using functools.reduce and we are going to use two cases, one using operator.mul and another using a lambda which both do the same thing (on the surface):



                        from timeit import timeit
                        setup = """
                        from functools import reduce
                        from operator import mul
                        """

                        print(timeit('reduce(mul, range(1, 10))', setup=setup))
                        print(timeit('reduce(lambda x, y: x * y, range(1, 10))', setup=setup))


                        Output:



                        1.48362842561
                        2.67425475375


                        operator.mul takes less time, as you can see.






                        share|improve this answer




























                          3














                          The basic answer to your question is this, multiplication using * is handled through C code. In essence if you write something in pure python its going to be slower than the C implementation, let me give you an example.



                          The operator.mul function is implemented in C, but a lambda is implemented in Python, we're going to try to find the product of all the numbers in an array using functools.reduce and we are going to use two cases, one using operator.mul and another using a lambda which both do the same thing (on the surface):



                          from timeit import timeit
                          setup = """
                          from functools import reduce
                          from operator import mul
                          """

                          print(timeit('reduce(mul, range(1, 10))', setup=setup))
                          print(timeit('reduce(lambda x, y: x * y, range(1, 10))', setup=setup))


                          Output:



                          1.48362842561
                          2.67425475375


                          operator.mul takes less time, as you can see.






                          share|improve this answer


























                            3












                            3








                            3







                            The basic answer to your question is this, multiplication using * is handled through C code. In essence if you write something in pure python its going to be slower than the C implementation, let me give you an example.



                            The operator.mul function is implemented in C, but a lambda is implemented in Python, we're going to try to find the product of all the numbers in an array using functools.reduce and we are going to use two cases, one using operator.mul and another using a lambda which both do the same thing (on the surface):



                            from timeit import timeit
                            setup = """
                            from functools import reduce
                            from operator import mul
                            """

                            print(timeit('reduce(mul, range(1, 10))', setup=setup))
                            print(timeit('reduce(lambda x, y: x * y, range(1, 10))', setup=setup))


                            Output:



                            1.48362842561
                            2.67425475375


                            operator.mul takes less time, as you can see.






                            share|improve this answer













                            The basic answer to your question is this, multiplication using * is handled through C code. In essence if you write something in pure python its going to be slower than the C implementation, let me give you an example.



                            The operator.mul function is implemented in C, but a lambda is implemented in Python, we're going to try to find the product of all the numbers in an array using functools.reduce and we are going to use two cases, one using operator.mul and another using a lambda which both do the same thing (on the surface):



                            from timeit import timeit
                            setup = """
                            from functools import reduce
                            from operator import mul
                            """

                            print(timeit('reduce(mul, range(1, 10))', setup=setup))
                            print(timeit('reduce(lambda x, y: x * y, range(1, 10))', setup=setup))


                            Output:



                            1.48362842561
                            2.67425475375


                            operator.mul takes less time, as you can see.







                            share|improve this answer












                            share|improve this answer



                            share|improve this answer










                            answered Feb 22 '14 at 17:21









                            Games BrainiacGames Brainiac

                            42.9k25108157




                            42.9k25108157























                                0














                                Usually, functional programming involving many computations is best made to take less time using memoization -- the basic idea is that if you feed a true function (something that always evaluates the same result for a given argument) the same thing twice or more, you're wasting time, time that could easily be saved by identifying common calls and storing whatever they evaluate down to into a hash table or other quickly-accessible object. See https://en.wikipedia.org/wiki/Memoization for basic theory. It is well-implemented in Common Lisp.






                                share|improve this answer




























                                  0














                                  Usually, functional programming involving many computations is best made to take less time using memoization -- the basic idea is that if you feed a true function (something that always evaluates the same result for a given argument) the same thing twice or more, you're wasting time, time that could easily be saved by identifying common calls and storing whatever they evaluate down to into a hash table or other quickly-accessible object. See https://en.wikipedia.org/wiki/Memoization for basic theory. It is well-implemented in Common Lisp.






                                  share|improve this answer


























                                    0












                                    0








                                    0







                                    Usually, functional programming involving many computations is best made to take less time using memoization -- the basic idea is that if you feed a true function (something that always evaluates the same result for a given argument) the same thing twice or more, you're wasting time, time that could easily be saved by identifying common calls and storing whatever they evaluate down to into a hash table or other quickly-accessible object. See https://en.wikipedia.org/wiki/Memoization for basic theory. It is well-implemented in Common Lisp.






                                    share|improve this answer













                                    Usually, functional programming involving many computations is best made to take less time using memoization -- the basic idea is that if you feed a true function (something that always evaluates the same result for a given argument) the same thing twice or more, you're wasting time, time that could easily be saved by identifying common calls and storing whatever they evaluate down to into a hash table or other quickly-accessible object. See https://en.wikipedia.org/wiki/Memoization for basic theory. It is well-implemented in Common Lisp.







                                    share|improve this answer












                                    share|improve this answer



                                    share|improve this answer










                                    answered Feb 22 '14 at 17:19









                                    miercoledimiercoledi

                                    21615




                                    21615















                                        Popular posts from this blog

                                        List item for chat from Array inside array React Native

                                        Thiostrepton

                                        Caerphilly