zoukankan      html  css  js  c++  java
  • 多线程和单线程的执行效率问题

    一提到多线程一般大家的第一感觉就是可以提升程序性能,在实际的操作中往往遇到性能的问题,都尝试使用多线程来解决问题,但多线程程序并不是在任何情况下都能提升效率,在一些情况下恰恰相反,反而会降低程序的性能。这里给出两个简单的例子来说明下:

    程序1:

    View Code
    import threading
    from time import ctime
    
    class MyThread(threading.Thread):
        def __init__(self, func, args, name):
            threading.Thread.__init__(self)
            self.name = name
            self.func = func
            self.args = args
    
        def run(self):
            print 'starting', self.name, 'at:',ctime()
            apply(self.func, self.args)
            print self.name, 'finished at:', ctime()
    
    def fun1(x):
        y = 0
        for i in range(x):
            y+=1
    
    def fun2(x):
        y = 0
        for i in range(x):
            y+=1
            
    def main():
        print 'staring single thread at:',ctime()
        fun1(10000000)
        fun2(10000000)
        print 'finished single thread at:',ctime()
    
        t1 = MyThread(fun1,(10000000,),fun1.__name__)
        t2 = MyThread(fun2,(10000000,),fun2.__name__)
        t1.start()
        t2.start()
        t1.join()
        t2.join()
        
        print 'all done'
        
    if __name__ == '__main__':
        main()

     该程序执行结果为:

    staring single thread at: Sat Dec 08 10:27:11 2012
    finished single thread at: Sat Dec 08 10:27:14 2012
    starting  fun1  at:  Sat Dec 08 10:27:14 2012
    starting  fun2  at:  Sat Dec 08 10:27:14 2012
    fun1  finished at:Sat Dec 08 10:27:21 2012
    fun2  finished at:Sat Dec 08 10:27:21 2012
    all done

    结果显示对于同样的问题多线程耗费了多一倍的时间,fun1,、fun2都是计算型程序,这就意味着两个代码都需要占用CPU资源,虽然采用了多线程但CPU资源是唯一的(不考虑多CPU多核的情况),同一时刻只能一个线程使用,导致多线程无法真正的并发,相反由于线程的切换的开销,效率反而有明显的下降。由此看以在单CPU的场景下对于计算密集型的程序,多线程并不能带来效率的提升。

    程序2:

    View Code
    import threading
    from time import ctime
    
    class MyThread(threading.Thread):
        def __init__(self, func, args, name):
            threading.Thread.__init__(self)
            self.name = name
            self.func = func
            self.args = args
    
        def run(self):
            print 'starting', self.name, 'at:',ctime()
            apply(self.func, self.args)
            print self.name, 'finished at:', ctime()
    
    def fun1(x):
        for i in range(x):
            fd = open('1','w')
            fd.close()
    
    def fun2(x):
        y = 0
        for i in range(x):
            y+=1
            
    def main():
        print 'staring single thread at:',ctime()
        fun1(15000)
        fun2(50000000)
        print 'finished single thread at:',ctime()
    
        t1 = MyThread(fun1,(15000,),fun1.__name__)
        t2 = MyThread(fun2,(50000000,),fun2.__name__)
        t1.start()
        t2.start()
        t1.join()
        t2.join()
        
        print 'all done'
        
    if __name__ == '__main__':
        main()

    该程序执行结果为:

    staring single thread at: Sat Dec 08 11:03:30 2012
    finished single thread at: Sat Dec 08 11:03:46 2012
    starting  fun1  at:  Sat Dec 08 11:03:46 2012
    starting  fun2  at:  Sat Dec 08 11:03:46 2012
    fun2 finished at: Sat Dec 08 11:03:55 2012
    fun1 finished at: Sat Dec 08 11:03:58 2012
    all done

    结果显示这个程序采用多线程比单线程的效率有明显的提升。这是由于fun1主要是文件的操作,fun2是计算操作,单线程的情况下,虽然两个程序主要使用不同的资源但是在线程内部只能串行执行,在IO操作的时候,CPU实际是无事可做。多线程的情况下,如果一个线程在等待IO操作,线程会马上调度到另外一个线程上,并发的使用了不同的资源。

    结论:

    线程本身由于创建和切换的开销,采用多线程不会提高程序的执行速度,反而会降低速度,但是对于频繁IO操作的程序,多线程可以有效的并发。

    对于包含不同任务的程序,可以考虑每个任务使用一个线程。这样的程序在设计上相对于单线程做所有事的程序来说,更为清晰明了,比如生产、消费者问题。

    在实际的开发中对于性能优化的问题需要考虑到具体的场景来考虑是否使用多线程技术。

    转载请注明原始出处:http://www.cnblogs.com/chencheng/archive/2012/12/08/2808348.html

  • 相关阅读:
    洛谷 1339 最短路
    洛谷 1330 封锁阳光大学 图论 二分图染色
    洛谷 1262 间谍网络 Tarjan 图论
    洛谷 1373 dp 小a和uim之大逃离 良心题解
    洛谷 1972 莫队
    洛谷 2158 数论 打表 欧拉函数
    洛谷 1414 数论 分解因数 水题
    蒟蒻的省选复习(不如说是noip普及组复习)————连载中
    关于筛法
    关于整数划分的几类问题
  • 原文地址:https://www.cnblogs.com/chencheng/p/2808348.html
Copyright © 2011-2022 走看看