C++ 将二进制文件中的复数值读入STL向量
我有一个已知数量的复远场电场值的二进制文件,它与频率有关。每个条目两个浮点值(32位),其中第一个浮点值是实部,第二个浮点值是虚部)。因此,文件大小为2*4*(频率数)C++ 将二进制文件中的复数值读入STL向量,c++,C++,我有一个已知数量的复远场电场值的二进制文件,它与频率有关。每个条目两个浮点值(32位),其中第一个浮点值是实部,第二个浮点值是虚部)。因此,文件大小为2*4*(频率数) 根据C++11标准,std::vector和std::complex必须在内存中连续(一个字可能太强?)。对于复值向量,这是真的吗 是否可以使用std::ifstreamread函数将上述二进制文件中的这些复杂值直接加载到预先分配的STL(std::vector)中的底层动态数组中 我应该补充的是,这些文件可以在GB范围内。分配
std::vector
和std::complex
必须在内存中连续(一个字可能太强?)。对于复值向量,这是真的吗std::ifstream
read函数将上述二进制文件中的这些复杂值直接加载到预先分配的STL(std::vector
)中的底层动态数组中我应该补充的是,这些文件可以在GB范围内。分配一个固定或动态的
浮点数组,读入,然后复制到std::vector
中是不切实际的。如果你想走这条路,你需要以下结构:
ifstream::read(&vec[0],nFreq*sizeof(complex))
对于预分配内存上的std::complex
构造
vec;
向量储备(nFreq);//如果由于文件太大而导致分配失败,请记住捕获异常
为了进一步“证明”(无法访问标准)您的位置和文件内容的有效性,a:
对于任何复数z,
重新解释_cast(z)[0]是z和
(z)[1]是z的虚部。
对于指向复数数组p和p元素的任何指针
任何有效的数组索引i,
重新解释_cast(p)[2*i]是复数p[i]的实部,并且
重新解释_cast(p)[2*i+1]是复数p[i]的虚部
这些要求本质上限制了std::complex三个专门化的实现,即声明两个且仅两个类型为value_type的非静态数据成员,具有相同的成员访问权限,分别包含实部和虚部
这是可能的,我认为-使用复杂的专门化,并在预大小的向量桶上使用placement new进行覆盖。如果您非常关心性能,请计算文件中有多少条目,然后分配一个固定大小的数组并将其直接读取到其中。您必须先使用调整大小
,这不是免费的。相比于说emplace\u back
你不会获得多少性能,我可能只会使用mmap
和reinterpret\u cast(…)
。那样的话,零开销。或者更好的方法是,除非你真的必须,否则不要同时将整个数据加载到内存中。优化在任何语言中都可以归结为相同的概念-最小化磁盘I/O(一次读取所有数据),使下一次使用的数据尽可能接近cpu寄存器(缓存->ram->磁盘)。你的方法是正确的,但是@MooingDuck的技术比你建议的要快得多。与往常一样,越优化,您的便利性就越少(失去向量功能)。然而,也许你想看看matlab中的MEX编译器?编译成c,然后手工优化剩下的是什么?我想说,没有必要重新发明轮子。你能再解释一下placement new的相关性和用途吗?初学者。@我确信你知道,SnaKeYeS1482.调用C++中的对象的构造函数为堆上的内存分配(使用new)。它不能保证内存在哪里。使用placement new,您可以准确地告诉它要使用的内存块,因为在您的情况下,您已经为它做好了准备。不过,我还是要先研究一下MEX如何编译您的MATLAB代码。他们这样做基本上就是为了这个原因
For any complex number z,
reinterpret_cast<T(&)[2]>(z)[0] is the real part of z and
reinterpret_cast<T(&)[2]>(z)[1] is the imaginary part of z.
For any pointer to an element of an array of complex numbers p and
any valid array index i,
reinterpret_cast<T*>(p)[2*i] is the real part of the complex number p[i], and
reinterpret_cast<T*>(p)[2*i + 1] is the imaginary part of the complex number p[i]