OpenCv
OpenCv

Reputation: 95

Threading in Python takes longer time instead of making it faster?

I wrote 3 different codes to compare having threads vs. not having threads. Basically measuring how much time I save by using threading and the result didn't make any sense.

Here are my codes:

 import time



def Function():

    global x 
    x = 0

    while x < 300000000:
        x += 1
    print x

e1 = time.clock()
E1 = time.time()

Function() 

e2 = time.clock()
E2 = time.time()

print e2 - e1
print E2 - E1 

When I ran this, I got this as output:

26.6358742929

26.6440000534

Then I wrote another function as shown below and split counting up to 300 million into counting 3, 100 millions:

 import time




def Function():

    global x 
    x = 0

    while x < 100000000:
        x += 1
    print x

def Function2():

    global x 
    x = 0

    while x < 100000000:
        x += 1
    print x       


def Function3():

    global x 
    x = 0

    while x < 100000000:
        x += 1
    print x 

e1 = time.clock()
E1 = time.time()

Function() 
Function2() 
Function3() 

e2 = time.clock()
E2 = time.time()

print e2 - e1
print E2 - E1   

The output of the following function was:

26.0577638729

26.0629999638

and lastly I created 3 threads and ran each function on a single thread:

import time
import threading

e1 = time.clock()
E1 = time.time()

def Function1():

    global x 
    x = 0

    while  x < 100000000:
        x += 1
    print x


def Function2():

    global x 
    x = 0

    while x < 100000000:
        x += 1
    print x    


def Function3():

    global x 
    x = 0

    while x < 100000000:
        x += 1
    print x    



new_thread1  = threading.Thread(target = Function1() , args = ())

new_thread2  = threading.Thread(target = Function2(), args = ())

new_thread3  = threading.Thread(target = Function3(), args = ())


e1 = time.clock()
E1 = time.time()

new_thread1.start()
new_thread2.start()
new_thread3.start()

e2 = time.clock()
E2 = time.time()

print e2 - e1
print E2 - E1 

The out put of this one was:

0.000601416222253

0.0

These numbers make no sense to me. I'm just trying to measure how much time does threading save me. I've looked up in the documentation and using time.time and time.clock made sense to me, but it doesn't make sense here. Also, the actual time for 1st and 2nd snippet were about 10 seconds and 3rd one about 5

Upvotes: 4

Views: 6907

Answers (1)

Joran Beasley
Joran Beasley

Reputation: 114088

you are calling it wrong ....

 new_thread1  = threading.Thread(target = Function1 , args = ())

note that you should not CALL the function when you create the thread

those timings really mean nothing they are both essentially zero because all you are timing is 3 instant return function calls to start

note to get the output you will need to wait for each thread to finish (since your current code does not do this )

EDIT FOR MORE INFO

with threading you are locked by the gil to one python instruction at a time... typically this is not a problem since you are usually waiting on disk io... In your example code however it is 100% computation so threading really doesnt improve your time ... Multiprocessing may as demonstrated below

import time
import threading
import multiprocessing

def fn():
    '''since all 3 functions were identical you can just use one ...'''
    x = 0
    while  x < 100000000:
        x += 1
    



def TEST_THREADS():
    new_thread1  = threading.Thread(target = fn , args = ())
    new_thread2  = threading.Thread(target = fn, args = ())
    new_thread3  = threading.Thread(target = fn, args = ())
    new_thread1.start()
    new_thread2.start()
    new_thread3.start()
    new_thread1.join()
    new_thread2.join()
    new_thread3.join()

def TEST_NORMAL():
    fn()
    fn()
    fn()
    
def TEST_MULTIPROCESSING():
    new_thread1  = multiprocessing.Process(target = fn , args = ())
    new_thread2  = multiprocessing.Process(target = fn, args = ())
    new_thread3  = multiprocessing.Process(target = fn, args = ())
    new_thread1.start()
    new_thread2.start()
    new_thread3.start()
    new_thread1.join()
    new_thread2.join()
    new_thread3.join
if __name__ == "__main__":  
    '''It is very important to use name == __main__ guard code with threads and multiprocessing'''
    import timeit
    print "Time to Run 1x: %0.2fs"%(timeit.timeit(fn,number=1),)
    print "NORMAL:%0.2fs"%(timeit.timeit(TEST_NORMAL,number=1),)
    print "Threaded: %0.2fs"%(timeit.timeit(TEST_THREADS,number=1),)
    print "Multiprocessing: %0.2fs"%(timeit.timeit(TEST_MULTIPROCESSING,number=1),)

I get the following output

Time to Run 1x: 3.71181102665
NORMAL:11.0136830117
Threaded: 23.392143814
Multiprocessing: 3.80878260515

Upvotes: 5

Related Questions