- mongodb - 在 MongoDB mapreduce 中,如何展平值对象?
- javascript - 对象传播与 Object.assign
- html - 输入类型 ="submit"Vs 按钮标签它们可以互换吗?
- sql - 使用 MongoDB 而不是 MS SQL Server 的优缺点
我有一些问题。给定以下 C++ 代码片段:
#include <boost/progress.hpp>
#include <vector>
#include <algorithm>
#include <numeric>
#include <iostream>
struct incrementor
{
incrementor() : curr_() {}
unsigned int operator()()
{ return curr_++; }
private:
unsigned int curr_;
};
template<class Vec>
char const* value_found(Vec const& v, typename Vec::const_iterator i)
{
return i==v.end() ? "no" : "yes";
}
template<class Vec>
typename Vec::const_iterator find1(Vec const& v, typename Vec::value_type val)
{
return find(v.begin(), v.end(), val);
}
template<class Vec>
typename Vec::const_iterator find2(Vec const& v, typename Vec::value_type val)
{
for(typename Vec::const_iterator i=v.begin(), end=v.end(); i<end; ++i)
if(*i==val) return i;
return v.end();
}
int main()
{
using namespace std;
typedef vector<unsigned int>::const_iterator iter;
vector<unsigned int> vec;
vec.reserve(10000000);
boost::progress_timer pt;
generate_n(back_inserter(vec), vec.capacity(), incrementor());
//added this line, to avoid any doubts, that compiler is able to
// guess the data is sorted
random_shuffle(vec.begin(), vec.end());
cout << "value generation required: " << pt.elapsed() << endl;
double d;
pt.restart();
iter found=find1(vec, vec.capacity());
d=pt.elapsed();
cout << "first search required: " << d << endl;
cout << "first search found value: " << value_found(vec, found)<< endl;
pt.restart();
found=find2(vec, vec.capacity());
d=pt.elapsed();
cout << "second search required: " << d << endl;
cout << "second search found value: " << value_found(vec, found)<< endl;
return 0;
}
在我的机器(Intel i7,Windows Vista)上,STL find(通过 find1 调用)的运行速度比手工循环(通过 find2 调用)快大约 10 倍。我首先认为 Visual C++ 执行某种矢量化(可能我在这里弄错了),但据我所见,汇编看起来不像它使用矢量化的方式。为什么 STL 循环更快?手工制作的循环与 STL-find 主体的循环相同。
我被要求发布程序的输出。无随机播放:
value generation required: 0.078
first search required: 0.008
first search found value: no
second search required: 0.098
second search found value: no
带有随机播放(缓存效果):
value generation required: 1.454
first search required: 0.009
first search found value: no
second search required: 0.044
second search found value: no
非常感谢,
杜莎。
附:我返回迭代器并写出结果(找到与否),因为我想阻止编译器优化,它认为根本不需要循环。搜索到的值显然不在 vector 中。
附言我被要求发布为查找功能生成的程序集。这里是:
found=find1(vec, vec.capacity());
001811D0 lea eax,[esp+5Ch]
001811D4 call std::vector<unsigned int,std::allocator<unsigned int> >::capacity (1814D0h)
001811D9 mov esi,dword ptr [esp+60h]
001811DD mov ecx,dword ptr [esp+64h]
001811E1 cmp esi,ecx
001811E3 je wmain+180h (1811F0h)
001811E5 cmp dword ptr [esi],eax
001811E7 je wmain+180h (1811F0h)
001811E9 add esi,4
001811EC cmp esi,ecx
001811EE jne wmain+175h (1811E5h)
found=find2(vec, vec.capacity());
001812AE lea eax,[esp+5Ch]
001812B2 call std::vector<unsigned int,std::allocator<unsigned int> >::capacity (1814D0h)
001812B7 mov ecx,dword ptr [esp+60h]
001812BB mov edx,dword ptr [esp+64h]
001812BF cmp ecx,edx
001812C1 je wmain+262h (1812D2h)
001812C3 cmp dword ptr [ecx],eax
001812C5 je wmain+34Fh (1813BFh)
001812CB add ecx,4
001812CE cmp ecx,edx
001812D0 jne wmain+253h (1812C3h)
find2 使用 ecx-register 代替 esi。这两个寄存器有什么区别?难道esi会假设指针正确对齐,从而带来额外的性能?
读取一些程序集引用 ecx 只是一个计数器,而 esi 是内存源。所以我认为 STL 算法知道 Random Access Iterator 正确对齐,因此使用内存指针。在非 STL 版本中,没有推测对齐方式。我说的对吗?
最佳答案
Visual C++ 的 find
算法使用未检查的迭代器,而您的手写循环使用的是检查的迭代器。
我的另一个猜测是你调用 我是个白痴。std::vector<t>::end()
在 find2
中循环的每次迭代, 而 std::find
只调用一次 begin 和 end 访问器。
关于c++ - STL find 的性能优于手工循环,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4580992/
我想显示一个图像(大于 iPhone 的屏幕),用户可以滚动。不难,我已经用这段代码完成了:在我的 .h 文件中 @interface mappa1 : UIViewController { IBO
bash 联机帮助页说: Redirecting Standard Output and Standard Error Bash allows both the standard output (fi
我将大量数据绑定(bind)到 TreeView 控件,因为数据是自然的类别层次结构。问题是它有很多。我已经设法通过仅绑定(bind)那些出现在可见树中的节点来消除大量开销,但这仍然在 ViewSta
我正在尝试为 mysql 操作与 redis 操作制作基准测试脚本。 这是我尝试过的: 1./ List of comment ids with a separate hash of comment
我很想知道是否有比 FileObserver 更好的方法来监视目录的文件更改/创建/删除。 FileObserver 需要持续引用它,这需要持续运行的服务,这很困难,也是一种不好的做法,对吧? 对于如
我创建了一个带有 NSOpenGLView 的窗口,我正在将 openGL 内容渲染到其中。 我想向 View 添加一些按钮和文本字段:我可以使用界面生成器(或代码)添加 NSTextFields 和
如何编码 JAXBElement 列表? 例如,我有一个无法注释的 POJO: public class APojo { private String aString; public APojo()
我正在开发一个博客,我的客户希望在其中使用大量图像(文章、标题、广告等)。他几乎不想要任何文本,因为他希望用阿拉伯语开发博客并且他对网络浏览器支持的任何字体都不满意,他也不想采用 EOT,他将每天更新
我想在文本字段上添加一个标签,该标签会在用户键入时发生变化。问题是文本字段的插入符号位于标签后面(如果我将标签放在文本字段前面)。我始终可以使文本字段的背景透明,并在标签和文本字段后面添加另一个禁用的
我正在尝试在 iOS 应用程序中创建一个特定的布局,其中“背景”是一个 MKMapView,覆盖层是一个 UIScrollView。这个想法是有两个屏幕,一个带有 map ,另一个带有一些附加信息。用
我需要在 UITableViewController 上放置一个 UIView,目前我是这样放置的 [self.navigationController.view addSubview:searchV
我有一个非常简单的问题要问:我需要在屏幕右下角的 ImageView 上放一个小 Logo ,整个屏幕都很大,但我不知道如何设置坐标或如何设置说 ImageViews 处于相对位置。 像这样: 最佳答
我试图让 mapView 覆盖整个 UITableViewCell 并禁用此 mapView 上的所有用户事件,但仍然可以单击单元格。但是,此 mapView(即使我将 subview 发送回)正在拦
我们即将获得 Java EE6(使用 Glassfish v3 作为引用实现)。计划发布时间为 12 月 9 日。虽然仍有相当多的公司正在努力将他们的代码库从早期版本迁移到 EE5,但我们处于开始开发
为什么(在 WPF、C#、 Entity Framework 中)将 ListBox 绑定(bind)到在 ObjectSet 上创建的 ObservableCollection(来自 Entity框
在 hibernate 中使用 @NamedQuery 而不是 @NamedNativeQuery 有什么好处,反之亦然。我无法发现确切的区别或在什么情况下我们应该使用 @NamedQuery 而不是
在 Dart 中,检查值是否为 == null似乎类似于检查它是否is Null .为什么前者更可取? 最佳答案 这是您正在进行的比较类型。在 == null ,您正在将对象/原始对象与 null 进
我使用的是 Java 1.6。我有一组项目,每个项目都有一个名称和一组组件。每个组件也有一个名称。 Set Class Item String name Set Class Compo
如果我想在我的应用程序中支持脚本,是否 scriptcs提供比仅使用普通 Vanilla 的任何特殊优势 Roslyn脚本引擎? 最佳答案 不幸的是,目前还没有太多关于托管 scriptcs 的文档,
我正在我的应用程序中使用 Struts 和 Spring jdbc 模板。 我必须在我们的代码中使用 Hibernate 模板。 谁能告诉我为什么要使用 Hibernate 模板? 使用 Spring
我是一名优秀的程序员,十分优秀!