- mongodb - 在 MongoDB mapreduce 中,如何展平值对象?
- javascript - 对象传播与 Object.assign
- html - 输入类型 ="submit"Vs 按钮标签它们可以互换吗?
- sql - 使用 MongoDB 而不是 MS SQL Server 的优缺点
我正在开发一个软实时事件处理系统。我想尽量减少我的代码中具有不确定时间的调用。我需要构建一个由字符串、数字、时间戳和 GUID 组成的消息。可能是 boost::variant
的 std::vector
。
我一直想在过去类似性质的代码中使用 alloca
。然而,当人们查看系统编程文献时,总是对这个函数调用非常谨慎。就我个人而言,在过去的 15 年中,我无法想到没有虚拟内存的服务器类机器,而且我知道 Windows 堆栈一次增长一个虚拟内存页面,所以我假设Unices也一样。这里(不再)没有砖墙,堆栈和堆一样可能会用完空间,所以什么给了?为什么人们不喜欢 aloca 呢?我可以想到许多负责任地使用 alloca 的用例(字符串处理任何人?)。
无论如何,我决定测试性能差异(见下文),alloca 和 malloc 之间存在 5 倍的速度差异(测试记录了我将如何使用 alloca)。那么,事情发生了变化吗?只要我们可以绝对确定对象的生命周期,我们是否应该小心翼翼地使用 alloca
(包装在 std::allocator
中)?
我厌倦了生活在恐惧中!
编辑:
好的,所以有限制,对于 Windows,这是一个链接时间限制。对于 Unix,它似乎是可调的。似乎页面对齐的内存分配器是有序的:D 任何人都知道通用的可移植实现:D?
代码:
#include <stdlib.h>
#include <time.h>
#include <boost/date_time/posix_time/posix_time.hpp>
#include <iostream>
using namespace boost::posix_time;
int random_string_size()
{
return ( (rand() % 1023) +1 );
}
int random_vector_size()
{
return ( (rand() % 31) +1);
}
void alloca_test()
{
int vec_sz = random_vector_size();
void ** vec = (void **) alloca(vec_sz * sizeof(void *));
for(int i = 0 ; i < vec_sz ; i++)
{
vec[i] = alloca(random_string_size());
}
}
void malloc_test()
{
int vec_sz = random_vector_size();
void ** vec = (void **) malloc(vec_sz * sizeof(void *));
for(int i = 0 ; i < vec_sz ; i++)
{
vec[i] = malloc(random_string_size());
}
for(int i = 0 ; i < vec_sz ; i++)
{
free(vec[i]);
}
free(vec);
}
int main()
{
srand( time(NULL) );
ptime now;
ptime after;
int test_repeat = 100;
int times = 100000;
time_duration alloc_total;
for(int ii=0; ii < test_repeat; ++ii)
{
now = microsec_clock::local_time();
for(int i =0 ; i < times ; ++i)
{
alloca_test();
}
after = microsec_clock::local_time();
alloc_total += after -now;
}
std::cout << "alloca_time: " << alloc_total/test_repeat << std::endl;
time_duration malloc_total;
for(int ii=0; ii < test_repeat; ++ii)
{
now = microsec_clock::local_time();
for(int i =0 ; i < times ; ++i)
{
malloc_test();
}
after = microsec_clock::local_time();
malloc_total += after-now;
}
std::cout << "malloc_time: " << malloc_total/test_repeat << std::endl;
}
输出:
hassan@hassan-desktop:~/test$ ./a.out
alloca_time: 00:00:00.056302
malloc_time: 00:00:00.260059
hassan@hassan-desktop:~/test$ ./a.out
alloca_time: 00:00:00.056229
malloc_time: 00:00:00.256374
hassan@hassan-desktop:~/test$ ./a.out
alloca_time: 00:00:00.056119
malloc_time: 00:00:00.265731
--编辑:家用机器、clang 和 google perftools 上的结果--
G++ without any optimization flags
alloca_time: 00:00:00.025785
malloc_time: 00:00:00.106345
G++ -O3
alloca_time: 00:00:00.021838
cmalloc_time: 00:00:00.111039
Clang no flags
alloca_time: 00:00:00.025503
malloc_time: 00:00:00.104551
Clang -O3 (alloca become magically faster)
alloca_time: 00:00:00.013028
malloc_time: 00:00:00.101729
g++ -O3 perftools
alloca_time: 00:00:00.021137
malloc_time: 00:00:00.043913
clang++ -O3 perftools (The sweet spot)
alloca_time: 00:00:00.013969
malloc_time: 00:00:00.044468
最佳答案
首先,即使有很多虚拟内存并不意味着您的进程将被允许填充它。在 *nix 上有堆栈大小限制,而堆则更宽松。
如果您只打算分配几百/几千个字节,请务必继续。除此之外的任何事情都将取决于任何给定系统上的限制 (ulimit),而这只是灾难的根源。
Why is the use of alloca() not considered good practice?
在我工作的开发箱 (Gentoo) 上,我的默认堆栈大小限制为 8192 kb。这不是很大,如果 alloca 溢出堆栈,则行为未定义。
关于c++ - 关于alloca的使用和滥用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5807612/
NSNotificationCenter 真的很酷,我们可以用它构建非常可扩展的应用程序。我的问题是:我们是否可以在应用程序中滥用 NSNotificationCenter,即密集使用它,还是它不是一
据我了解,标签是“ anchor ”标签,它有三个用途: 1) 描述并命名页面上的项目 2) 单击时将用户转到另一个页面 Yahoo! 3) 单击时将用户发送到同一页面中的另一个位置 Foo! 有人
我有一个使用 OpenMP 并行化 for 循环的程序。在循环内部,线程将写入共享变量,因此我需要同步它们。但是,我有时会遇到段错误或双重释放或损坏错误。任何人都知道会发生什么?感谢致敬!这是代码:
我很确定过去曾有开发人员严重滥用了我们可怜的 ASP.NET session 状态。 Session 很想帮助跟踪请求之间的事情,但只能做这么多!请帮我减轻它的痛苦,让它和我们一起快乐地工作。 有谁知
关闭。这个问题是opinion-based .它目前不接受答案。 想改进这个问题?更新问题,以便 editing this post 可以用事实和引用来回答它. 4年前关闭。 Improve this
Git 本质上是事件存储的实现,其中存储的数据是目录结构中的文件。已知可以可靠地解决问题: 存储更改历史记录 向客户端传输最少的数据以获取最新数据 可以回滚到之前的状态 可以通过在 Git 上编写包装
我有两项服务-Lincr和LinkBunch。 Lincr是简单的简捷URL缩短服务,而LinkBunch可让您将多个链接缩短为一个链接。我在服务中张贴了太多垃圾邮件,因此不得不关闭Lincr。现在,
我必须接管一个包含多个层、服务和组件的巨型整体。 当我浏览代码时,我首先意识到的是 MDC 的使用. 一些例子: public void setContextOrderId(String orderI
我正在尝试制作一种从外部文件中提取电子邮件信息并将其存储在字符串中的方法。我正在使用 .get 来提取字符,但我的调试器说:没有重载函数的实例与参数列表匹配。它还说它不能将第三个参数从 const c
我的 UI 中需要一个标签来容纳最多 32 个字符而不变形,因此我启用了自动收缩并将行数更改为 0: 这是我在 IB 上的标签: 现在,当我运行应用程序时,它会在屏幕外运行: 我怎样才能使它相应地适应
我有一个整数列表(当前),我想检查这个列表是否包含预期列表中的所有元素,甚至不包含列表 notExpected 中的一个元素,所以代码如下: List expected= new ArrayL
目前正在阅读 Bloch 的Effective Java(第 2 版),他以粗体字指出,在 Web 应用程序中过度使用 POST 本质上是不好的。不幸的是,他没有具体说明原因。 这让我大吃一惊,因为当
提前为第一个可能很愚蠢的帖子道歉。虽然有很多关于这个主题的 Material ,但其中很少有是确定的和/或对我来说可以理解的。 我有一个 AlignedArray 模板类,可以在堆上以任意对齐方式动态
MSDN 建议 RegisterWindowMessage() 函数仅用于注册要在进程之间发送的消息。如果需要在一个进程内发送消息,可以从 WM_APP 到 0xBFFF 范围内安全地选择它。 但是在
我已经阅读了很多关于在每个 SELECT 上使用许多 JOIN 语句的关系数据库。但是,我一直想知道滥用这种方法从长远来看是否会出现任何性能问题。 例如,假设我们有一个users 表。我通常会添加“最
所以我有一些使用保留字 property 的遗留代码,嗯,错了。在继承的基类中,它们基本上已实现。 class TestClass(object): def __init__(self, pr
出于方便和安全的原因,我想使用 using 语句从池中分配和释放对象 public class Resource : IDisposable { public void Dispose()
您很可能已经知道,在 JQuery 中选择文档中具有特定 CSS 类的所有元素,然后使用链接将公共(public)事件处理程序分配给所选元素很简单: $(".toolWindow").click(to
我需要解析一个 xml 文件,它实际上是一个非常大的树结构的图像,所以我使用 XmlReader 类来“动态”填充树。每个节点仅通过 ReadSubtree() 函数传递它期望从其父节点获得的 xml
我想知道这些指南的用途: 1 - 我多久可以读取 NSUserDefaults 2 - 我可以在 NSUserDefaults 中合理存储多少数据 显然,NSUserDefaults 的使用量是有限制
我是一名优秀的程序员,十分优秀!