- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
假设我正在编写一个简单的缓冲区类。这个缓冲区将充当标准 C 对象数组的简单包装器。它还应该向后兼容,以便与将简单数组作为输入的现有函数一起使用。
这里的目标是使这个缓冲区在速度和内存使用方面都高效。由于堆栈分配总是比堆快,我想将堆栈上的所有内容分配到某个阈值,如果它变大,则在堆上重新分配。如何有效地完成这项工作?
我研究了一下,显然 std::string 做了类似的事情。我只是不确定如何。我所拥有的最接近的解决方案是(伪代码,未编译):
template <typename T, int MinSize>
class Buffer
{
public:
void Push(const T& t)
{
++_size;
if (_size > MinSize && _heap == NULL)
{
// allocate _heap and copy contents from stack
// _stack is unused and wasted memory
}
else if (_heap != NULL)
{
// we already allocated _heap, append to it, re-allocate if needed
}
else
{
// still got room on stack, append to _stack
}
}
void Pop()
{
--_size;
if (_size <= MinSize && _heap != NULL)
{
// no need for _heap anymore
// copy values to _stack, de-allocate _heap
}
else if (_heap != NULL)
{
// pop from heap
}
else
{
// pop from stack
}
}
private:
T _stack[MinSize];
T* _heap;
int _size;
};
如您所见,当缓冲区增长超过 MinSize
时,_stack
只是浪费空间。此外,如果 Buffer 足够大,push 和 pop 的成本可能会特别高。另一种解决方案是将前几个元素始终放在堆栈上,并将溢出放在堆上。但这意味着 Buffer 无法“转换”为简单数组。
有更好的解决方案吗?如果这是在 std::string 中完成的,有人可以指出如何或提供一些资源吗?
最佳答案
我建议您使用指针 _data
而不是 _heap
,后者始终指向您的数据存储。 _heap == NULL
会变成 _data == _stack
等等,但是在所有不改变数据长度的情况下,您都可以避免区分大小写。
您当前的草图不包含 _capacity
成员来跟踪当前分配的空间。您将需要它来实现“附加到它,如果需要则重新分配”部分,除非您想要为堆分配容器的每个长度变化重新分配。
您也可以考虑在数据适合堆栈时不释放堆空间。否则,可能会有应用程序在该边界处添加和删除单个元素,每次都会导致分配。所以要么实现一些hysteresis或者在分配堆空间后根本不释放堆空间。一般来说,我会说释放堆内存应该与缩小堆内存一起使用。您可能希望自动执行这两项操作,以响应某个函数调用,例如 shrink_to_fit
。 ,或者根本不做,但是在类似情况下只做一个而不做另一个没有什么意义。
除此之外,我相信您的解决方案几乎就是您所希望的。也许为 MinSize
提供一个默认值。如果 MinSize
很小,以避免堆栈溢出,那么浪费那个空间就不会成为什么大问题,对吧?
当然,最终这一切都取决于您的实际应用,因为这种形式的大量未使用的堆栈分配可能会产生不利影响,例如关于堆栈内存的缓存。考虑到默认分配器也可以非常智能这一事实,对于给定的应用程序,您可能应该进行基准测试,看看您是否真的从这种优化中获益匪浅。
关于c++ - 在栈和堆之间动态切换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12336778/
栈一种常见的特殊线性数据结构,其特殊之处在于其操作顺序,下面会详细介绍,也正因为其特性,因此栈可以轻松解决表达式求值、括号匹配、递归算法、回溯算法等等问题。 01、定义 栈的特殊性表现为操作受
目录 实践1 —— 从字符串中移除星号 栈和数组存储数据的方式一样,它们都只是元素的列表。不同之处在于栈的以下3个限制: 数据只能从栈末插入; 数据只
准备工作 工具:idea+jdk8 技术要求:java基础语法 编码环节 首先,我们得先确定下来,用什么数据来模拟栈的操作。由于是一个一个的元素放入栈里面,我们可以考虑用数组来实现。
0. 学习目标 栈和队列是在程序设计中常见的数据类型,从数据结构的角度来讲,栈和队列也是线性表,是操作受限的线性表,它们的基本操作是线性表操作的子集,但从数据类型的角度来讲,它们与线性表又有着巨大的不
在可以使用递归(在堆栈中存储状态)和对象创建(在堆中创建新对象)的场景中。 问题 在对象创建和递归之间进行选择时应考虑哪些参数? 我的研究得出以下结论(需要验证这一点) 当可用内存较少时:使用递归 可
下面是我编写的用于检查内存对齐的示例程序。 Pavan@Pavan-pc:~/working_dir/pavan/C$ cat mem3.c #include #include
Instapaper 和 Twitterrific 等应用启动的 View 不是其导航堆栈的 Root View 。我们知道这一点,因为初始 View 已经有一个后退按钮。 Instapaper 推出
有没有办法在调试或正常运行期间的某个时刻可视化 Activity 堆栈? 最佳答案 您可以通过 Activity 管理器获取一些有用的信息。 ActivityManager manag
我想编写一个应用层协议(protocol),在发送 GET 请求时使用 TCP 返回特定的 ASCII 文本。我读了第一HTTP specification和 the SMTP specificati
1、堆和栈的速度性能分析 堆和栈是jvm内存模型中的2个重要组成部分,自己很早以前也总结过堆和栈的区别,基本都是从存储内
一: 概念 栈,同样是一种特殊的线性表,是一种last in first out(lifo)的形式,现实中有很多这样的例子,
java中stack类继承于vector,其特性为后进先出(lastinfirstout). 入栈和出栈实例图: 实例图的java代码实例: ?
1、单链表 1、在我们数据结构中,单链表非常重要。它里面的数据元素是以结点为单位,每个结点是由数据元素的数据和下一个结点的地址组成,在java集合框架里面 LinkedList、Ha
本文实例讲述了Python编程实现双链表,栈,队列及二叉树的方法。分享给大家供大家参考,具体如下: 1.双链表 ?
我一遍又一遍地阅读定义,但我仍然不明白ARM中的SP和LR是什么?我了解PC(它显示下一条指令的地址),SP和LR可能类似,但我只是不明白它是什么。你能帮我一下吗? 编辑:如果你能用例子来解释它,那就
我必须使用索引 0 作为堆栈的顶部,并且在实现此操作时遇到问题。我得到了所有 null,但输出 100、200 和 300 是我得到的唯一数字。我忽略的实现有什么问题吗? push 方法应该实现 Ar
我正在用 Java 解决汉诺塔问题。我选择使用 Stacks 作为钉子,除了 move 方法之外,一切都正常。我有规范和 JUnit 测试类,目前通过了 7 项测试中的 6 项,但在移动测试中失败了。
这个问题在这里已经有了答案: 关闭 11 年前。 Possible Duplicate: Does this type of memory get allocated on the heap or
首先,抱歉我的英语不好。我将尝试解释我的问题: 我有一个 RootViewController(基于导航的项目)。因此,它显示了表格 View ,当用户选择表格的一行 (didSelectRowAtI
我有一个看起来像这样的类 class A { int b; void B() { int c; } } int main() { A asdf;
我是一名优秀的程序员,十分优秀!