c++ 迭代器取消引用耗费了大量时间

xqk2d5yq  于 2022-12-30  发布在  其他
关注(0)|答案(1)|浏览(132)

我解决了一个集合操作的问题,比如上界,迭代器解引用等等,它在20秒内就解决了。一般的问题是我在一组数字上迭代(i*(i-1)/2)直到它小于2 * 10^5,然后完成一个DP向量。所以在我的算法中,对于每个数字“x”我得到上界,“up”,然后从头开始迭代这些数字直到达到“up”。该解决方案做同样的事情,但是它不运行upper_bound和解引用,而是直接计算i*(i-1)/2,这是我先前计算并存储在vset中的。两种算法的运算次数几乎相同,大约为8010^6,这不是一个超级大的数字。但是我的代码需要20秒,解决方案需要2秒。
请看看我的代码,让我知道如果你需要更多的信息:
1-vset具有600个数字,其全部是i
(i-1)/2形式的数字;小于2*10^5
2-vset在增加时已排序
3-两种算法中最终矢量“v”完全相同
4-cnt,两者的操作数几乎相同。80,000,000
5-你可以用n = 199977测试代码。

6-在我的电脑上,corei 7 32 G内存,需要20秒,在服务器上接受大约200毫秒,这对我来说很奇怪。

typedef long long int llint;
int n; cin >> n;
vector<llint> v(n+1, INT_MAX); 
llint p = 1;
llint node = 2;

llint cnt = 0;
for (int i = 1; i <= n; i++)
{
    if (v[i] == INT_MAX)
    {
        for (int s = 1; (s * (s - 1)) / 2 <= i; ++s)
            v[i] = min(v[i], v[i - (s * (s - 1)) / 2] + s) , cnt++;
    }
    else cnt ++ ;
}
cout << cnt << endl; // works in less than 2 seconds

第二个解决方案需要20秒。

typedef long long int llint;
int n; cin >> n;
vector<llint> v(n+1, INT_MAX); 
llint p = 1;
llint node = 2;
vector<int> vset;
while (p <= n) // only 600 numbers 
{
    v[p] = node;
    vset.push_back(p);
    node++;
    p = node * (node - 1) / 2;
}
llint cnt = 0;
for (int i = 1; i <= n; i++)
  {
    if (v[i] == INT_MAX)
    {
        auto up = upper_bound(vset.begin(), vset.end(), i);
        for (auto it = vset.begin(); it != up; it++) // at most 600 iteration
        {
            cnt++;
            int j = *it;
            v[i] = min(v[j] + v[i - j], v[i]);
        }
    } 
    else cnt ++ ;
   }
cout << cnt << endl; // cnt for both is around 84,000,000

所以这个问题是关于一些我想不明白的事情:这里的哪个操作是昂贵的?**遍历迭代器?取消引用迭代器?这里没有更多的区别,但是时间是十倍。**谢谢

eoxn13cs

eoxn13cs1#

感谢所有评论并帮助我解决这个问题的人。我意识到我性能缓慢的原因是调试模式。所以我把它改为发布模式,它在不到2秒的时间内工作。有一个similar question,可能会帮助你更多。我在Windows 10上使用Visual Studio C++

相关问题