加快For循环下嵌套的IF循环的速度

本教程将介绍加快For循环下嵌套的IF循环的速度的处理方法,这篇教程是从别的地方看到的,然后加了一些国外程序员的疑问与解答,希望能对你有所帮助,好了,下面开始学习吧。

加快For循环下嵌套的IF循环的速度 教程 第1张

问题描述

在二维平面上,有一个以(0,0)为中心、半径为??的大圆。它包围了∼100左右的较小的圆,这些圆随机分布在父圆上,否则相对于原点的半径和位置是已知的。(一些较小的子圆可能部分或全部位于较大的子圆内。)

整个平面被均匀地网格化为像素,边是水平的和垂直的(沿坐标轴)。像素的大小是固定的,并且是先验已知的,但在其他方面比父圆的大小小得多;整个父圆大约有1000个像素。我们得到了所有这些特殊网格(中心)的二维笛卡尔坐标。包围这些特殊网格中至少一个的子圆被命名为*特殊"子圆,以备以后使用。

现在,想象所有的3D空间都充满了大约1亿个粒子。我的代码尝试将这些粒子相加到每个特殊的子圆内。

我设法调试了我的代码,但似乎当我处理如此大量的粒子时,它非常慢,如下所示。我想看看我是否可以使用任何技巧将其加快至少一个数量级。

.
.
.
for x, y in zip(vals1, vals2):  # vals1, vals2 are the 2d position array of the *special* grids each with a 1d array of size ~1000
 enclosing_circles, sub_circle_catalog, some_parameter_catalog, totals = {}, [], [], {}


 for id, mass in zip(ids_data, masss_data): # These two arrays are equal in size equal to an array of size ~100,000,000
  rule1 = some_condition  # this check if each special grid is within each circle
  rule2 = some_other_condition  # this makes sure that we are only concerned with those circles larger than some threshold size 

  if (rule1 and rule2):
calculated_property = some_function

if condition_3:
 calculated_some_other_property = some_other_function

 if condition_4:
  some_quantity = something
  enclosing_circles[id] = float('{:.4f}'.format(log10(mass)))
  some_parameter[id] = float('{:.3e}'.format(some_quantity))


 # choose all sub-circles' IDs enclosing the special pixel
 enclosing_circles_list = list(enclosing_circles.keys())
 some_parameter_list = list(some_parameter.keys())
 sub_circle_catalog += [(enclosing_circles[i], 1) for i in enclosing_circles_list]
 some_parameter_catalog += [(enclosing_circles[i], some_parameter[j]) for i, j in zip(enclosing_circles_list, some_parameter_list)]

# add up all special grids in each sub-circle when looping over all grids
for key, value in sub_circle_catalog:
 totals[key] = totals.get(key, 0) + value
totals_dict = collections.OrderedDict(sorted(totals.items()))
totals_list = list(totals.items())


with open(some_file_path, "a") as some_file:
 print('{}'.format(totals_list), file=some_file)
 some_file.close()
.
.
.

推荐答案

第二个For下的rule1和rule2耗时最长。

内联rule1rule2。如果and知道第一部分为假,则它不会计算第二部分。也试着调换一下,看看这样会不会更好。

根据这些规则的计算方式的详细信息,您可能会发现其他类似快捷方式的机会。


始终分析以查找瓶颈。您可能会浪费大量时间来优化其他不会有太大帮助的部分。

尽可能走捷径;不要浪费时间计算不需要的东西。

通过内联来避免嵌套循环中的函数调用。在CPython中调用有点慢。

展开内部循环以减少循环开销。

尽可能在循环外计算,而不是每次循环都重做。


考虑使用Nutika、Cython或PyPy编译整个代码。(或者只使用Cython或Numba的较慢部分。)

考虑用Julia重写这一部分,它更快、更容易从Python中调用。最好提取并调用整个内部循环,而不仅仅是它的主体,以避免每个循环的调用开销。

考虑在可能的情况下使用NumPy向量化计算,即使它只是循环的一部分。Numpy的内部循环比Python的快得多,这会占用更多的内存。如果你能让NumPy矢量化工作,你也许能通过使用GPU的CuPy或可以处理更大数据集的Dask来获得更大的加速比。

好了关于加快For循环下嵌套的IF循环的速度的教程就到这里就结束了,希望趣模板源码网找到的这篇技术文章能帮助到大家,更多技术教程可以在站内搜索。