【发布时间】:2019-06-27 01:18:32
【问题描述】:
在二维平面上,有一个以 (0,0) 为中心、半径为 ???????? 的大圆。它包含了大约 100 个更小的圆,随机分布在父圆上,否则具有已知的半径和相对于原点的位置。 (有可能一些较小的子圈部分或全部在一些较大的子圈内。)
整个平面被均匀地网格化为像素,边为水平和垂直(沿坐标轴)。像素的大小是固定的,是先验已知的,但远小于父圆的大小;整个父圆上有大约 1000 个 特殊 像素。我们得到了所有这些特殊网格(中心)的二维笛卡尔坐标。包含这些特殊网格中的至少一个的那些子圆被命名为 *special" 子圆以供以后使用。
现在,想象一下所有这些 3D 空间都充满了大约 100,000,000 个粒子。我的代码尝试在每个特殊的子圈内添加这些粒子。
我设法调试了我的代码,但是当我处理如此大量的粒子时,它似乎非常慢,如下所示。我想看看我是否可以使用任何技巧将其加速至少一个数量级。
.
.
.
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耗时最长。
-
我建议在这些点上施加一个空间细分网格并将网格与圆圈相交。如果一个单元格完全在一个圆圈内,那么您可以计算一次该单元格中的点的总和。
-
@Allan 通过分析,通常意味着在某些外部监控软件下运行程序,该软件将逐行记录详细信息,例如执行时间、调用次数、缓存未命中、分支错误预测或任何内容否则你指定。对于Python,我个人使用kernprof
标签: python performance for-loop if-statement nested-loops