当前位置: 首页 > 面试题库 >

为什么以下简单的并行化代码比Python中的简单循环慢得多?

松烨烨
2023-03-14
问题内容

一个简单的程序,用于计算数字平方并存储结果:

    import time
    from joblib import Parallel, delayed
    import multiprocessing

    array1 = [ 0 for i in range(100000) ]

    def myfun(i):
        return i**2

    #### Simple loop ####
    start_time = time.time()

    for i in range(100000):
        array1[i]=i**2

    print( "Time for simple loop         --- %s seconds ---" % (  time.time()
                                                               - start_time
                                                                 )
            )
    #### Parallelized loop ####
    start_time = time.time()
    results = Parallel( n_jobs  = -1,
                        verbose =  0,
                        backend = "threading"
                        )(
                        map( delayed( myfun ),
                             range( 100000 )
                             )
                        )
    print( "Time for parallelized method --- %s seconds ---" % (  time.time()
                                                               - start_time
                                                                 )
            )
    #### Output ####
    # >>> ( executing file "Test_vr20.py" )
    # Time for simple loop         --- 0.015599966049194336 seconds ---
    # Time for parallelized method --- 7.763299942016602 seconds ---

这两个选项的数组处理是否可能有所不同?我的实际程序会有一些更复杂的东西,但这 是我需要尽可能简单地并行化的一种计算方式 ,但没有这种结果。

System Model: HP ProBook 640 G2, Windows 7,
              IDLE for Python System Type: x64-based PC Processor:
              Intel(R) Core(TM) i5-6300U CPU @ 2.40GHz,
              2401 MHz,
              2 Core(s),
              4 Logical Processor(s)

问题答案:

从以下文档中threading

如果您知道所调用的函数基于已编译的扩展,该扩展会在大多数计算过程中释放Python全局解释器锁(GIL)…

问题在于,在这种情况下,您不知道这一点。Python本身仅允许一次运行一个线程(python解释器每次执行python操作时都会锁定GIL)。

threading仅当myfun()大部分时间都用在已编译的Python扩展程序中 并且该扩展程序释放GIL 时,它才有用。

Parallel代码之所以令人尴尬地缓慢,是因为您正在做大量工作来创建多个线程-然后您一次只能执行一个线程。

如果使用multiprocessing后端,则必须将输入数据复制到四个或八个进程中的每个进程中(每个内核一个),在每个进程中进行处理,然后再将输出数据复制回去。复制将会很慢,但是如果处理比仅仅计算一个平方稍微复杂一点,那可能是值得的。测量并查看。



 类似资料:
  • 问题内容: 我们正在做一些和实现Python编写的。其他人选择了Java。我们的执行时间非常不同。我使用cProfile查看我在哪里出错,但实际上一切都很好。是的,我也使用。但是我想问一个简单的问题。 此摘要在我的计算机上耗时31.40s。 此代码的Java版本在同一台计算机上花费1秒或更短的时间。我想类型检查是此代码的主要问题。但是我应该为我的项目做很多这样的操作,我认为9999 *9999的数

  • 我刚开始学习Haskell,但是现在没有循环是非常令人沮丧的。我想出了如何为函数编写循环。然而,我的问题是,我想在迭代循环时输出一些结果。似乎我必须使用debug来执行这个简单的任务。 所以现在我只想举一个例子,说明如何在主结构中打印字符串10次。 换句话说,我想这样做10次: 谢谢。我觉得这对我的任务很有启发。

  • 问题内容: 我正在重写一些旧的存储过程,并且在使用函数而不是内联代码时遇到了意外的性能问题。 该功能非常简单,如下所示: 因此,我有两个相同的查询,但是一个使用该函数,另一个使用查询本身进行计算: 现在,使用内联代码的查询运行速度比使用该函数的查询快3倍。 问题答案: 您拥有的是一个标量UDF(接受0到n个参数并返回一个标量值)。除非使用常量参数调用,否则此类UDF通常会导致查询的逐行操作,从而导

  • 我有一个看起来很简单的问题,但由于某种原因我无法绕过它。基本上我的程序正在导致一个无限循环,我不知道为什么。 下面是我陷入的特定循环: 当我运行它时,它总是问我输入列#。我给它一个数字,它接受这个数字,$response变为True,但while循环继续运行,就好像<code>的$response</code>为false一样。我是Perl新手,所以可能我遗漏了一些东西,但是($response=

  • 据我所知,流比传统的旧编程更快。 然而,当我运行下面的代码时,结果是我没有预料到的。 输出为:22857304

  • 问题内容: 我有一堂课,我已经简化为: 我想对这个东西进行排序。所以我创建了一个简单的copmarator: 然后,我使用的两个参数形式。 这对于我的测试用例来说很好用,但是有时由于数组以奇怪但可重复的顺序结束而完全出错。怎么会这样? 问题答案: 整数溢出…或更确切地说是下溢。 相反,进行显式比较: 如果您确定差异不会“绕回”,则可以使用减法。例如,当所讨论的值被约束为非负数时。