Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/python-3.x/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 加快一段长python代码的速度,这段代码只因一个块而被证明很慢_C++_Python 3.x_Performance_Numpy - Fatal编程技术网

C++ 加快一段长python代码的速度,这段代码只因一个块而被证明很慢

C++ 加快一段长python代码的速度,这段代码只因一个块而被证明很慢,c++,python-3.x,performance,numpy,C++,Python 3.x,Performance,Numpy,我们在空间中有一个巨大的体积,充满了大量的粒子(~10^8),它们具有已知的质量阵列(“HI_质量”)、3d位置(“HI_位置”)和一些有趣的分数(“HI_分数”)。 本卷中还有一些虚构的球体(~10^3),它们具有不同但已知的质量阵列(“质量数据”)、位置(“位置数据”)和大小(“半径数据”) 我们想把每个假想球体中的所有气体粒子(对气体质量的贡献很小)相加,得到上面提到的每个假想球体的“气体质量”。一旦我们有了每个球体的质量,我们就计算出一些称为“sigma_-HI”的量。如果这个量高于某个

我们在空间中有一个巨大的体积,充满了大量的粒子(~10^8),它们具有已知的质量阵列(“HI_质量”)、3d位置(“HI_位置”)和一些有趣的分数(“HI_分数”)。 本卷中还有一些虚构的球体(~10^3),它们具有不同但已知的质量阵列(“质量数据”)、位置(“位置数据”)和大小(“半径数据”)

我们想把每个假想球体中的所有气体粒子(对气体质量的贡献很小)相加,得到上面提到的每个假想球体的“气体质量”。一旦我们有了每个球体的质量,我们就计算出一些称为“sigma_-HI”的量。如果这个量高于某个阈值,那么我们将以{id:mass}字典的形式跟踪该球体的单个质量,以便以后使用它进行进一步的计算。第三个块将永远在整个代码的上下文中运行,这段代码非常长,并且没有包含在内;我只复制了那部分被证明很慢的代码

import numpy as np

enclosing_circles_gas = {}
#info of imaginary spheres where *_data are stored arrays based on some random (otherwise positive integer) ids
for id, position, radius, mass zip(id_data, position_data, radius_data, mass_data):  

    if (mass >= low_mass_cutoff):
        for i in np.where(HI_fraction > 0):                            # HI_fraction is a 1d array
            gas_mass = 0
            if (np.linalg.norm(HI_position[i] - position) <= radius):  # HI_position and position: 3d array of particles and single sphere vector
                gas_mass += HI_mass[i]*HI_fraction[i]                  # HI_mass and HI_fraction are 1d arrays of particles and their fractions
            if (gas_mass/mass >= 1.0e-6):
                enclosing_circles_gas[id] = float('{:.4f}'.format(mass))
将numpy导入为np
包围圈气体={}
#基于一些随机(或正整数)ID的数组存储*u数据的虚拟球体信息
对于id、位置、半径、质量压缩(id\u数据、位置\u数据、半径\u数据、质量\u数据):
如果(质量>=低质量截止):
对于np中的i,其中(HI_分数>0):#HI_分数是一维数组
气体质量=0
如果(np.linalg.norm(高位置[i]-位置)=1.0e-6):
包围圈气体[id]=浮点数('{.4f}'。格式(质量))
我的问题是: 如何使用C++在Python中转换这个非常慢的块来加快整个代码? 我尝试过的事情: 将嵌套循环更改为列表理解(但这仍然很慢)

如果(质量>=低质量截止):
气体质量=总和(高质量[i]*高质量分数[i],对于np中的i,其中(高质量分数>0)[0]如果(np.linalg.norm(高位置[i]-位置)=1.0e-6):
包围圈气体[id]=浮点数('{.4f}'。格式(质量))

您应该找到一种方法来记录循环各个部分的计时。但是,如果是字符串到双精度到字符串的转换,那么下面如何从数字中截断数字而不是正确的四舍五入呢

import math

def trunc_digits(x, digits):
    d = math.log10(abs(x)) - digits
    d = int(math.ceil(d))
    d = math.pow(10, d)
    m = math.fmod(x, d)
    x = x - m
    return x

x = 9.87654321e-6
print (x, "->", trunc_digits(x, 4))
y = 9.87654321e6
print (y, "->", trunc_digits(y, 4))

a = -1.87654321e-6
print (a, "->", trunc_digits(a, 4))
b = -1.87654321e6
print (b, "->", trunc_digits(b, 4))

在内部循环中使用float-to-string-to-float转换听起来可能非常慢。尝试使用
round(number[,ndigits])
相反,可能是这样。查看CPython代码,我发现它使用相同的方法进行舍入,尽管是C。它看起来仍然很慢。是否需要在小数点后4位进行正确舍入?也许可以使用
fmod()截断数字
或诸如此类。Wix,谢谢!这听起来很有希望。我真的不需要这么多小数位。我只需要2 sig.fig.当放入科学记数法时(例如2.3乘以10^(6))。请告诉我如何在这个例子中使用它好吗?如果你把它作为一个答案发布,我将不胜感激。现在已经太晚了,我明天会尝试运行你的建议。@wilx,我使用了第一个建议,但它仍然运行缓慢。考虑到我希望比率大于某个非常小的正数,我不会确定如何处理第二个建议。这应作为trunc_数字(“,4”)应用于代码的第10行,其中整个if条件应位于.Right?这是计算距离并根据某个最大值进行检查的地方。正如您所知,所有my*_数据文件实际上都是.txt文件格式中的一些字符串,所有其他参数都是从中读取的。@Allan作为此位的替换:
float(“{.4f}.”格式(mass))
事实上,您希望在最后使用
浮点
,因此我会使用
浮点(trunc_digits(mass,4))
。我也进行了测试。运行代码所花费的时间没有变化:(那么时间就花在了其他地方。您是否尝试过在下面运行代码?
import math

def trunc_digits(x, digits):
    d = math.log10(abs(x)) - digits
    d = int(math.ceil(d))
    d = math.pow(10, d)
    m = math.fmod(x, d)
    x = x - m
    return x

x = 9.87654321e-6
print (x, "->", trunc_digits(x, 4))
y = 9.87654321e6
print (y, "->", trunc_digits(y, 4))

a = -1.87654321e-6
print (a, "->", trunc_digits(a, 4))
b = -1.87654321e6
print (b, "->", trunc_digits(b, 4))