【发布时间】:2011-05-12 20:18:06
【问题描述】:
我正在优化 Visual Studio 2008 SP1 中的一段代码。知道unorder_map 在恒定时间插入/删除/查找方面很棒,所以我通过使用unordered_map 作为我的主要数据结构来优化代码。请看下面的代码。
....
typedef std::tr1::unordered_map <__int64, int> umap_id;
const int text1_length = text1.GetLength();
const int text2_length = text2.GetLength();
const int max_d = text1_length + text2_length - 1;
const bool doubleEnd = (64 < max_d);
vector<set<pair<int, int> > > v_map1;
vector<set<pair<int, int> > > v_map2;
vector<int> v1(2 *max_d, 0);
vector<int> v2(2 *max_d, 0);
int x, y;
__int64 footstep;
umap_id footsteps(max_d * 2);
bool done = false;
const bool forward = ((text1_length + text2_length) % 2 == 1);
for (int d = 0; d < max_d; ++d)
{
// Walk forward path one step
v_map1.push_back(set<pair<int, int> >());
for (int k = -d; k <= d; k += 2)
{
if (k == -d || (k != d && v1[k - 1 + max_d] < v1[k + 1 + max_d]))
x = v1[k + 1 + max_d];
else
x = v1[k - 1 + max_d] + 1;
y = x - k;
if (doubleEnd)
{
footstep = (__int64) ((__int64)x << 32 | y);
if (!forward)
footsteps[footstep] = d;
else if (footsteps.find(footstep) != footsteps.end())
done = true;
}
....
}
}
....
但事实证明它仍然很慢。鉴于我的输入相对较小(max_d=946),它运行了 20 多秒。
我对 release 版本进行了分析器分析,分析器显示该行:footsteps[footstep] = d; 是主要的罪魁祸首,它运行了 447931 次,耗时约 20 秒。
请注意,同一循环体中还有另一行代码:else if (footsteps.find(footstep) != footsteps.end()),它执行了相同的次数(即 447931 次),但花费的秒数要少得多。
unordered_map 的 operator::[] 对我来说似乎是一个黑匣子。我不明白为什么要花这么长时间。这是一个32 位 应用程序。任何帮助表示赞赏。
【问题讨论】:
-
您使用的是哪种 STL 实现?
-
微软的 Visual C++,谢谢
-
太多
::和<、>以及要被 C. 删除的演员表 -
Visual C++ 的哪个版本(包括应用的服务包)?我知道在 VC2008 SP1 中对 TR1 库进行了修复,因此如果您在没有服务包的情况下运行 VC2008,您可能想查看 SP 是否有帮助(或查看 VC2010 是否修复了问题)。
-
@Michael,感谢您的回复。我的 VC++ 更新了,版本 3.5 SP 1。
标签: c++ visual-c++ stl hash optimization