我在其他帖子中读到,这似乎是组合哈希值的最佳方式.有人可以打破这一点,并解释为什么这是最好的方法吗?
template <class T>
inline void hash_combine(std::size_t& seed, const T& v)
{
std::hash<T> hasher;
seed ^= hasher(v) + 0x9e3779b9 + (seed<<6) + (seed>>2);
}
Run Code Online (Sandbox Code Playgroud)
编辑:另一个问题只是要求神奇的数字,但我想知道整个功能,而不仅仅是这一部分.
继上一个与堆使用限制相关的问题之后,我正在寻找一个好的标准C++类,以一种既节省内存又提高速度的方式处理大数据数据.我一直在使用单个malloc/HealAlloc分配数组,但是在使用各种调用的多个trys之后,继续犯下堆碎片.因此,除了移植到64位之外,我得出的结论是使用一种机制,允许我拥有一个跨越多个较小内存片段的大型数组.我不希望每个元素都有一个alloc,因为它的内存效率很低,所以计划是编写一个覆盖[]运算符的类,并根据索引选择一个合适的元素.是否已经有一个体面的班级来做这件事,或者我最好自己动手?
根据我的理解和一些谷歌搜索,32位Windows进程理论上应该可以解决高达2GB的问题.现在假设我已经安装了2GB,并且各种其他进程和服务占用大约400MB,你认为我的程序可以合理地期望从堆中获得多少可用内存?
我目前正在使用各种风格的Visual C++.
编辑 按照Poita的帖子,我尝试了一个std :: deque,在VS2008上使用以下测试;
#include <deque>
using namespace std;
struct V
{
double data[11];
};
struct T
{
long data[8];
};
void dequeTest()
{
deque<V> VQ;
deque<T> TQ;
V defV;
T defT;
VQ.resize(4000000,defV);
TQ.resize(8000000,defT);
}
Run Code Online (Sandbox Code Playgroud)
上述数据的总内存为608MB,如果我使用直接malloc或HeapAlloc,则需要<1秒.deque resizes最初占用了950MB,然后慢慢开始退回.15分钟后,dequeTest()完成了,只使用了6MB的内存显示进程,这可能更多地与运行时间有关.我也尝试使用各种推送选项填充双端队列,但性能非常糟糕,我不得不提前爆发.我可以提供一个比defualt更好的分配器来获得更好的响应,但从表面来看,deque并不是这项工作的类.请注意,这也可能与deque的MS VS2008实现有关,因为在这个类中似乎有很多与性能相关的非常依赖于实现的实现.
我想,是时候写我自己的大数组了.
第二次编辑: 使用以下内容立即分配较小的数量,产生1.875GB;
#define TenMB 1024*1024*10
void SmallerAllocs()
{
size_t Total = 0;
LPVOID p[200];
for (int i = 0; i < 200; i++)
{
p[i] = malloc(TenMB);
if (p[i])
Total += …Run Code Online (Sandbox Code Playgroud) 我需要初始化一个非常大的多维std::array数据:
class Thing;
class World
{
public:
World() : space{nullptr} {};
~World() = default;
private:
static unsigned int const size = 1000;
std::array<std::array<std::array<std::unique_ptr<Thing>, size>, size>, size> space;
};
Run Code Online (Sandbox Code Playgroud)
如果你试图实例化它,G ++ 4.8.2扼杀:它消耗所有可用的内存,不会返回.也就是说,编译器挂起,我永远不会得到可执行文件. 为什么是这样? 请注意,clang ++没有问题.
注意:我完全意识到将这么多数据放在堆栈上会溢出它. 在堆上初始化它的最佳方法是什么? 我认为制作space一个引用(分配内存)是最好的方法,但我无法弄清楚语法.
我必须在当前项目中使用稀疏向量来处理某些事情.但是,由于我不负责该项目,我不能使用我想要的任何外部库.我只有STL和OpenCV可用.
我已经查看了几个stackoverflow回答的问题,但他们要么专注于一个特定的方法,比较有限数量的方法(2)和外部库,当他们专门处理稀疏向量.实现稀疏矩阵也有一些很好的想法.
我想要的是一个稀疏的向量(索引总是在一维,数据与这个问题无关).我想要的东西不是自己实现的项目,但可以用于超出示范目的(例如,我希望获得合适的速度而不是太多的内存开销)并且希望重新以后用过.我考虑的选项包括:
std::map来存储值(或者可以创建一个非常简单的包装器,在索引零元素的情况下返回默认值)std::vector< std::pair < int , data_type > >我可以将索引和数据存储在std::pair元素中的位置对于作为稀疏向量的通用目的,这些解决方案中的任何一个是更好/更差吗?我知道每件事的每一种方法都有它起伏不定,但是我们非常赞赏有关选择哪种方法的建议.此外,如果有人认为他有更好的建议,推荐一种我没有考虑过的方法会更受欢迎.
我具体情况的用法如下:
尽管如此,正如我在原始问题中所写的那样,我想了解通用稀疏矢量实现的建议.
我有一棵巨大的树,可能需要几千兆字节.节点结构如下.您会注意到我将最后一个成员设置为大小为1的数组.原因是我可以Node使用灵活的大小来过度分配.类似于C本身作为灵活阵列成员支持的内容.我可以使用std::unique_ptr<T[]>或std::vector<T>替代,但问题是,每个树节点有双重动态分配,双间接和额外的缓存未命中.在我的上一次测试中,这使我的程序花费了大约50%的时间,这对我的应用程序来说根本不可接受.
template<typename T>
class Node
{
public:
Node<T> *parent;
Node<T> *child;
/* ... */
T &operator[](int);
private;
int size;
T array[1];
};
Run Code Online (Sandbox Code Playgroud)
最简单的实现operator[]方式是这样.
template<typename T>
T &Node::operator[](int n)
{
return array[n];
}
Run Code Online (Sandbox Code Playgroud)
它应该在大多数理智的C++实现中正常工作.但是,由于C++标准允许疯狂的实现进行数组边界检查,因为我知道这在技术上调用了未定义的行为.那我可以这样做吗?
template<typename T>
T &Node::operator[](int n)
{
return (&array[0])[n];
}
Run Code Online (Sandbox Code Playgroud)
我在这里有点困惑.[]原始类型的运算符只是一个语法糖*.因此(&array[0])[n]相当于(&*(array + 0))[n],我认为可以将其清理为array[n],使一切与第一个相同.好的,但我仍然可以这样做.
template<typename T>
T &Node::operator[](int n)
{
return *(reinterpret_cast<T *>(reinterpret_cast<char *>(this) + offsetof(Node<T>, array)) + n);
}
Run Code Online (Sandbox Code Playgroud)
我希望我现在摆脱可能未定义的行为.也许内联汇编会更好地展示我的意图.但我真的必须走这么远吗?有人可以向我澄清事情吗? …