C++ 使用查找表优化代码
这部分代码运行时间太长,我正在寻找一种优化它的方法。我认为查找表是最快的方法,但我可能错了。我的程序有一个main for循环,对于main for循环中的每一次迭代,一个嵌套循环都要经过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++) {
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算法,也可以。没有太多的东西可以优化什么废话。没有太多的东西可以优化什么非