C++ 使用查找表优化代码

C++ 使用查找表优化代码,c++,optimization,lookup,2d-vector,C++,Optimization,Lookup,2d Vector,这部分代码运行时间太长,我正在寻找一种优化它的方法。我认为查找表是最快的方法,但我可能错了。我的程序有一个main for循环,对于main for循环中的每一次迭代,一个嵌套循环都要经过1233487次迭代,然后在满足条件的情况下通过if语句。主for循环经过898281迭代,因此它必须经过898281*1233487计算。我将如何创建一个查找表来优化这些计算/是否有更好的方法来优化我的代码 for (int i = 0; i < all_neutrinos.size(); i++) {

这部分代码运行时间太长,我正在寻找一种优化它的方法。我认为查找表是最快的方法,但我可能错了。我的程序有一个main for循环,对于main for循环中的每一次迭代,一个嵌套循环都要经过
1233487
次迭代,然后在满足条件的情况下通过if语句。主for循环经过
898281
迭代,因此它必须经过
898281*1233487
计算。我将如何创建一个查找表来优化这些计算/是否有更好的方法来优化我的代码

for (int i = 0; i < all_neutrinos.size(); i++)
{ //all_neutrinos.size() = 898281
    int MC_count = 0;  //counts per window in the Monte Carlo simulation
    int count = 0; //count per window for real data

    if (cosmic_ray_events.size() == MC_cosmic_ray_events.size()) 
    {
        for (int j = 0; j < cosmic_ray_events.size(); j++) 
        { //cosmic_ray_events.size() = 1233487
            if ((MC_cosmic_ray_events[j][1] >= (all_neutrinos[i][3] - band_width))
             && (MC_cosmic_ray_events[j][1] <= (all_neutrinos[i][3] + band_width)))
            {
                if ((earth_radius * fabs(all_neutrinos[i][2] - MC_cosmic_ray_events[j][0]))
                     <= test_arc_length)
                {
                    MC_count++;
                }
            }   

            if ((cosmic_ray_events[j][7] >= (all_neutrinos[i][3] - band_width))
             && (cosmic_ray_events[j][7] <= (all_neutrinos[i][3] + band_width)))
            {
                if(earth_radius * fabs(all_neutrinos[i][2] - cosmic_ray_events[j][6])
                    <= test_arc_length)
                {
                    count++;
                }
            }
        }
        MCcount_out << i << "     " << MC_count << endl;
        count_out << i << "     " << count << endl;
    }
}
for(inti=0;i=(所有中微子[i][3]-带宽))

&&(MC_宇宙线事件[j][1]第一个
宇宙线原始事件
MC_宇宙线事件
是完全不相关的。将其设为两个循环

[1]
排序
MC\u宇宙线事件
[7]
排序
宇宙线事件
排序
所有中微子
[3]
排序

这不需要进行就地排序——如果需要,可以将指针或索引数组排序到其中

从宇宙线事件的高水位和低水位指数设置为0开始

现在,检查所有的中微子。对于每一个中微子,前进到高水位
MC\u宇宙线事件[highwater][1]>所有中微子[i][3]+带宽)
。然后推进低水,直到
MC\u宇宙线事件[lowwater][1]>=所有中微子[i][3]-带宽)

在半开范围
j=低水位到但不包括高水位
,运行:

if (
  (earth_radius * fabs(all_neutrinos[i][2] - MC_cosmic_ray_events[j][0]))
  <= test_arc_length
) {
  MC_count++;
}
if(
(地球半径*fabs(所有中微子[i][2]-MC宇宙线事件[j][0]))

首先,宇宙原始事件和宇宙射线事件是完全不相关的。把它分成两个循环

[1]
排序
MC\u宇宙线事件
[7]
排序
宇宙线事件
排序
所有中微子
[3]
排序

这不需要进行就地排序——如果需要,可以将指针或索引数组排序到其中

从宇宙线事件的高水位和低水位指数设置为0开始

现在,检查所有的中微子。对于每一个中微子,前进到高水位
MC\u宇宙线事件[highwater][1]>所有中微子[i][3]+带宽)
。然后推进低水,直到
MC\u宇宙线事件[lowwater][1]>=所有中微子[i][3]-带宽)

在半开范围
j=低水位到但不包括高水位
,运行:

if (
  (earth_radius * fabs(all_neutrinos[i][2] - MC_cosmic_ray_events[j][0]))
  <= test_arc_length
) {
  MC_count++;
}
if(
(地球半径*fabs(所有中微子[i][2]-MC宇宙线事件[j][0]))

没有太多需要优化的地方。计数非常高,也没有太多的困难计算。你可以做一些明显的优化,比如存储(所有中微子[i][3]+/-bandwitdth)在进入j循环之前,编译器可能已经这样做了,但这肯定会提高调试模式下的性能

您是否尝试过将j形环的两半分开并拥有两个j形环?如:

   auto all_neutrinos_2 = all_neutrinos[i][2];
   //... precompute bandwidth limits
   for (int j = 0; j < cosmic_ray_events.size(); j++) 
    { //cosmic_ray_events.size() = 1233487
        auto MC_events = MC_cosmic_ray_events[j][1];
        if ((all_neutrinos_lower <= MC_events) &&(MC_cosmic_ray_events[j][1] <= all_neutrinos_higher))
        {
            if ((earth_radius * fabs(all_neutrinos_2 - MC_cosmic_ray_events[j][0]))
                 <= test_arc_length)
            {
                MC_count++;
            }
        }
    }


    for (int j = 0; j < cosmic_ray_events.size(); j++) 
    { //cosmic_ray_events.size() = 1233487
        auto events = cosmic_ray_events[j][7];
        if ((all_neutrinos_lower <= events) && (events  <= all_neutrinos_higher))
        {
            if(earth_radius * fabs(all_neutrinos_2 - cosmic_ray_events[j][6])
                <= test_arc_length)
            {
                count++;
            }
        }
    }
auto all_中微子2=all_中微子[i][2];
//…预计算带宽限制
对于(int j=0;j如果((所有中微子都较低没有太多需要优化的。计数非常高,并且没有太多困难的计算。你可以做一些明显的优化,比如存储(所有中微子[i][3]+/-bandwitdth)在进入j循环之前,编译器可能已经这样做了,但这肯定会提高调试模式下的性能

您是否尝试过将j形环的两半分开并拥有两个j形环?如:

   auto all_neutrinos_2 = all_neutrinos[i][2];
   //... precompute bandwidth limits
   for (int j = 0; j < cosmic_ray_events.size(); j++) 
    { //cosmic_ray_events.size() = 1233487
        auto MC_events = MC_cosmic_ray_events[j][1];
        if ((all_neutrinos_lower <= MC_events) &&(MC_cosmic_ray_events[j][1] <= all_neutrinos_higher))
        {
            if ((earth_radius * fabs(all_neutrinos_2 - MC_cosmic_ray_events[j][0]))
                 <= test_arc_length)
            {
                MC_count++;
            }
        }
    }


    for (int j = 0; j < cosmic_ray_events.size(); j++) 
    { //cosmic_ray_events.size() = 1233487
        auto events = cosmic_ray_events[j][7];
        if ((all_neutrinos_lower <= events) && (events  <= all_neutrinos_higher))
        {
            if(earth_radius * fabs(all_neutrinos_2 - cosmic_ray_events[j][6])
                <= test_arc_length)
            {
                count++;
            }
        }
    }
auto all_中微子2=all_中微子[i][2];
//…预计算带宽限制
对于(int j=0;j如果((所有中微子都降低了,你想在查找表中查找什么?只有在每次程序运行时都有相同结果的计算时,查找表才适用,而且看起来你不能说这些计算是否可以提前重复,是吗?顺便说一句,if后面不必跟else语句。你可以删除从代码中清空其他内容。我认为您应该能够通过对元素进行排序来降低复杂性,然后使用类似于
std::merge
的代码。您当前有
N*M
,而您应该有类似
N log N+M log M
的代码。您可以查看Bentley Ottmann算法,也可以查看。您想在yo中查找什么您的查找表?查找表仅适用于每次程序运行时都给出相同结果的计算,并且看起来您不能说这些计算是否可以提前重复,对吗?顺便说一句,if后面不必跟else语句。您可以从代码中删除空的else。我认为您应该能够通过对元素进行排序来降低复杂性,然后使用类似于
std::merge
的代码。您当前有
N*M
,而您应该有类似
N log N+M log M
的代码。您可以看看Bentley Ottmann算法,也可以。没有太多的东西可以优化什么废话。没有太多的东西可以优化什么非