Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/135.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++;:如何处理未使用的空向量消耗的RAM? 我有一个C++软件,它执行基于代理的模拟。在模拟中,有群体s包含斑块es,其中个体s包含两个单倍型s。每个单倍型包含12个载体,每个载体用于跟踪不同类型的基因 class Haplotype { std::vector<A> genesA; std::vector<B> genesB; std::vector<C> genesC; std::vector<D> genesD; .... }; 类单倍型 { std::载体基因; std::载体基因b; std::载体基因; std::载体基因; .... };_C++_Algorithm_Design Patterns - Fatal编程技术网

C++;:如何处理未使用的空向量消耗的RAM? 我有一个C++软件,它执行基于代理的模拟。在模拟中,有群体s包含斑块es,其中个体s包含两个单倍型s。每个单倍型包含12个载体,每个载体用于跟踪不同类型的基因 class Haplotype { std::vector<A> genesA; std::vector<B> genesB; std::vector<C> genesC; std::vector<D> genesD; .... }; 类单倍型 { std::载体基因; std::载体基因b; std::载体基因; std::载体基因; .... };

C++;:如何处理未使用的空向量消耗的RAM? 我有一个C++软件,它执行基于代理的模拟。在模拟中,有群体s包含斑块es,其中个体s包含两个单倍型s。每个单倍型包含12个载体,每个载体用于跟踪不同类型的基因 class Haplotype { std::vector<A> genesA; std::vector<B> genesB; std::vector<C> genesC; std::vector<D> genesD; .... }; 类单倍型 { std::载体基因; std::载体基因b; std::载体基因; std::载体基因; .... };,c++,algorithm,design-patterns,C++,Algorithm,Design Patterns,然而,在实践中,用户永远不会使用超过一种或两种类型的基因。这意味着每个未使用的向量都会消耗几个字节(至少两个指针)。对于具有大量基因和少量个体的模拟,这是可以忽略不计的。然而,对于基因少、个体多的模拟来说,这些额外的字节可能开始起作用。性能(CPU时间和RAM)至关重要 有没有一个好的设计模式可以让我处理这个问题?只需按需将载体添加到单倍型 我不知道它是否是您正在寻找的,但我认为,您可以存储一个只包含有用向量的向量向量(使用多态性),而不是存储12个只包含一个或两个有用向量的向量 例如,为基因类

然而,在实践中,用户永远不会使用超过一种或两种类型的基因。这意味着每个未使用的向量都会消耗几个字节(至少两个指针)。对于具有大量基因和少量
个体的模拟,这是可以忽略不计的。然而,对于基因少、个体多的模拟来说,这些额外的字节可能开始起作用。性能(CPU时间和RAM)至关重要


有没有一个好的设计模式可以让我处理这个问题?只需按需将载体添加到
单倍型

我不知道它是否是您正在寻找的,但我认为,您可以存储一个只包含有用向量的向量向量(使用多态性),而不是存储12个只包含一个或两个有用向量的向量

例如,为基因类型创建基类:

class Gene
{
    // Make it pure virtual (abstract) for example
};
然后创建继承该基类的12种不同类型的基因:

class A : public Gene // Gene type number 1
{
    // ...
};

...

class L : public Gene // Gene type number 12
{

};
因此,你所有的12种基因都是
基因

然后,在
单倍型
中,可以按如下方式存储有用的基因:

class Haplotype
{
    std::vector<std::vector<Gene*>> genes;
};
类单倍型
{
std::载体基因;
};
这样,您只存储在载体中有用的基因,而不存储其他基因。当然,这种使用多态性的设计意味着存储指针而不是值

您可以在
Haplotype
中添加一个方法,该方法检索其组件的真实类型(成功的动态类型转换),使其从“用户端”不易察觉

我不知道这个解决方案是否对你有好处,但我希望它能有所帮助


编辑:


如果您在C++17之前,因此无法使用
std::variant
,我认为这可能是另一种选择。

我认为无论您做什么,都必须为即将到来的数据保留一些空间

向量有可能“浪费”一些未使用的空间。此外,对象本身使用一些内存,如您所说

但是,当您使用阵列时,您拥有完全控制权。 带有
std::vector[]基因您可以完全使用所需的内存。
但现在您必须知道哪个索引表示哪种类型(A、B、C…)。这些信息会再次消耗你的内存。。。
此外,如果要添加另一个阵列,还必须复制并重新分配该阵列

通过使用指针并使用
nullptr
初始化它们,可以避免为每个向量使用分配的内存。然后按需分配。 这样只会浪费指针的空间。
按照当前的实现方式,您将初始化每个向量对象(,可能还有一些保留空间)。

如果所有基因类型的大小大致相同,那么这样做可能是一个胜利:

union基因
{
A A;
B B;
C C;
D;
};
类单倍型
{
std::载体基因;
中部本德国际机场;
公众:
一个getA(intidx){
返回基因[idx].a;
}
B getB(intidx){
返回基因[idx+aEnd].b;
}
C getC(int idx){
返回基因[idx+bEnd].c;
}
D getD(intidx){
返回基因[idx+cEnd].d;
}
};
向载体中添加一个给定类型的新基因可以在固定时间内完成(你不需要把所有的东西都推回去),只要你不关心单个类型的顺序

例如,如果你需要添加一个B,你可以将它移动到第一个C的位置,然后将其移动到第一个D的位置,然后将其推到末端。然后,您将依次递增
bEnd
cEnd

例如:

最初:
[A1、A2、A3、B1、B2、C1、C2、C3、C4、D1、D2、D3、D4、D5]

在折弯处添加新的B:
[A1、A2、A3、B1、B2、B3、C2、C3、C4、D1、D2、D3、D4、D5]

更换收回的C:
[A1、A2、A3、B1、B2、B3、C2、C3、C4、C1、D2、D3、D4、D5]

在末尾添加被逐出的D:
[A1、A2、A3、B1、B2、B3、C2、C3、C4、C1、D2、D3、D4、D5、D1]

要在固定时间内去除一个基因,你可以反过来做类似的事情。关键是要保持不变,即所有As都在所有Bs之前,所有Cs之前,所有Ds之前

此方案允许您以较少的开销获得成功:每种类型只有一个int(用于存储结束索引),以换取更难看的代码,在添加或删除基因时有一点额外的时间开销,以及无法保持每组基因的插入顺序。这些缺点是否值得,取决于你


此外,如果类型的大小有显著差异,则此设计将导致每个元素的开销,因为联合必须至少与其最大的成员一样大。

std::vector只要每个类型的大小相同,变体就可以获胜。如果不是,空向量的开销通常在两个指针和一个大小上。
std::variant
将为向量中的每个元素带来一些恒定的开销。我认为这个问题有点不够明确。你会有多少个单倍型?A、B、C……的尺寸是多少。。。等你希望用它们做什么
std::vector
在我的系统上是24字节。如果你真的有这么多的单倍型,以至于每个单倍型的288字节的开销是不可接受的,那么你可能会想要一些手工优化的东西,考虑到数据访问模式…@Remi.b什么是A、b、C等类型?这需要