许多堆栈分配与动态分配

时间:2012-02-10 08:39:29

标签: c++ arrays dynamic stack heap

在第二维将具有已知大小的多维数组中(尽管每个第一维度不同),对于硬编码这些数组的实际构建,它是否会更快性能

int* number[1000];

int secondDim[1];
number[0] = secondDim;

int secondDimTwo[2];
number[1] = secondDim;

等。 1000次(我知道,我知道)

或动态分配每个第二维:

for(int i = 0; i < 1000; i++)
    number[i] = new int[i+1];

试着在这里围绕一个概念。

4 个答案:

答案 0 :(得分:4)

作为一般规则,您可以假设,堆栈分配会更快。只记得堆栈容量有限,过度使用大堆栈分配的数组可能导致等待它...堆栈溢出!

无论如何,你的问题是有效的,但到目前为止我看到的解决方案非常有限。问题是,您可以轻松创建实用程序类型,它将充当三角矩阵,然后由特定用例决定是否将其存储在堆栈或堆中。观察:

namespace meta
{
    template <size_t N>
    struct sum
    {
        static const int value = (N + 1) * N / 2;
    };
}

template <size_t Size>
struct MultiArray
{
    // actual buffer
    int numbers[ meta::sum<Size>::value ];

    // run-time indexing
    int* getArray(size_t dimensions)
    {
        // get sum of (dimensions-1)
        size_t index = (dimensions * (dimensions-1)) >> 1;
        return &numbers[index];
    }

    // compile-time indexing
    template <size_t dimensions>
    int* getArray()
    {
        size_t index = meta::sum<dimensions - 1>::value ;
        return &numbers[ index ];
    }

    int* operator[](size_t index)
    {
        return getArray(index);
    }
};

现在取决于你在哪里存放它。

MultiArray<1000> storedOnStack;
MultiArray<1000>* storedOnHeap = new MultiArray<1000>();

你必须访问内部数组:

int* runTimeResolvedArray = storedOnStack.getArray(10);
int* compileTimeResolvedArray = storedOnStack.getArray<10>();
int* runTimeResolvedArray2 = storedOnStack[10];
storedOnStack[10][0] = 666;

希望这有帮助!

编辑: 我还必须说我不喜欢“堆栈分配”这个术语。这是误导。堆栈分配基本上只是堆栈指针寄存器的增加。因此,如果在堆栈上“分配”100个字节,则指针将增加100个字节。但是如果你在堆上分配100个字节,那么它就变得复杂了 - 当前的分配器必须找到合适的空内存空间,更新alloc map等等,等等。

如果是一次性分配 - 继续在堆上执行,动态分配的开销将不会显着。但如果每秒多次,那么选择堆栈分配。此外,堆栈数组可能更快访问,因为堆栈内容更可能在缓存中。但显然真正庞大的数组不适合缓存。因此,anwser是: profile

答案 1 :(得分:1)

如果您已经知道所需阵列的大小,则应在堆栈中使用数组 请注意,通常,动态分配比堆栈上的分配更昂贵 如果性能差异足以满足您的情况,则只能通过分析确定。

此外,避免动态分配,因为除非您使用基于 RAII 的某种资源管理,否则它们更容易出错。

答案 2 :(得分:1)

更好的方法是一次性分配整个数组,以便所有数据都是连续的(更好的缓存)。

int * arr; arr = malloc(sizeof(int)* sum(1,n));你必须定义和函数。

只需分配一个2d数组(第一个暗淡)并将指针设置为arr中的正确位置。

答案 3 :(得分:1)

直到你实际分析过,并知道动态分配 是一个问题:

std::vector<std::vector<int> > number;
for ( size_t i = 0; i < 1000; ++ i ) {
    number.push_back( std::vector<int>( i + 1 );
}

或(可能稍微快一点,特别是如果您的编译器没有 移动语义):

std::vector<std::vector<int> > number( 1000 );
for ( size_t i = 0; i != number.size() ; ++ i ) {
    number[i].resize( i + 1 );
}

如果这确实会导致性能问题,或者可能只是为了更好 在封装中,您可以编写一个表示数据的简单类 结构:

class TriangularMatrix
{
    std::vector<int> myData;
    size_t mySize;

    size_t rowIndex( size_t i ) const
    {
        return (i * (i + 1)) / 2;
    }
public:
    TriangularMatrix( size_t size )
        : myData( rowIndex( size ) )
        , mySize( size )
    {
    }
    int* operator[]( size_t i )  // Returns row
    {
        assert( i < mySize );
        return &myData[rowIndex( i )];
    }
    int const* operator[]( size_t i ) const  // Returns row
    {
        assert( i < mySize );
        return &myData[rowIndex( i )];
    }
    int& operator( int i, int j )  // indexation
    {
        assert( j <= i );
        return operator[]( i )[ j ];
    }
    int const& operator( int i, int j ) const  // indexation
    {
        assert( j <= i );
        return operator[]( i )[ j ];
    }
};

事实上,我认为这样的事情会更清洁,更多 可读的。