在我们的C++课程中,他们建议不再在新项目中使用C++数组.据我所知,Stroustroup本人建议不要使用数组.但是有显着的性能差异吗?
我一直听说C++比Java更有效(这就是大多数游戏都是用C++开发的原因).
我写了一个小算法来解决Java和C++中的"八皇后谜题",使用完全相同的算法,然后开始提高数字或方块.当到达20*20甚至22*22的检查板时,看起来Java更有效(3秒对C++的66秒).
我不知道为什么,但我从C++开始,所以我可能会犯一些巨大的性能错误,所以我很乐意接受任何可以帮助我理解正在发生的事情的信息.
下面是我在Java中使用的代码:
import java.awt.Point;
import java.util.ArrayList;
import java.util.List;
public class HuitDames {
    /**
     * La liste des coordnnées des dames.
     */
    private static List<Point> positions = new ArrayList<>();
    /**
     * Largeur de la grille.
     */
    private static final int LARGEUR_GRILLE = 22;
    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        int i = 1;
        placerDame(i);
        for (Point point : positions) {
            System.out.println("(" + point.x + "; " + point.y + ")"); …我试图解决C ++中的编码问题,该问题计算素数的数量小于非负数的数量n。
所以我首先想出了一些代码:
int countPrimes(int n) {
    vector<bool> flag(n+1,1);
    for(int i =2;i<n;i++)
    {
        if(flag[i]==1)
            for(long j=i;i*j<n;j++)
                flag[i*j]=0;
    }
    int result=0;
    for(int i =2;i<n;i++)
        result+=flag[i];
    return result;
}
这需要88毫秒,并使用8.6 MB的内存。然后,我将代码更改为:
int countPrimes(int n) {
    // vector<bool> flag(n+1,1);
    bool flag[n+1] ;
    fill(flag,flag+n+1,true);
    for(int i =2;i<n;i++)
    {
        if(flag[i]==1)
            for(long j=i;i*j<n;j++)
                flag[i*j]=0;
    }
    int result=0;
    for(int i =2;i<n;i++)
        result+=flag[i];
    return result;
}
这需要28毫秒和9.9 MB。我真的不明白为什么在运行时间和内存消耗上都存在这样的性能差距。我已阅读相类似的问题这一个和那一个,但我仍然困惑。
编辑:我的运行时间与11.5 MB的存储器替换之后减少至40毫秒vector<bool>与vector<char>。
我是C++的新手.我正在阅读迈克尔道森的"通过游戏编程开始C++".但是,我对编程并不陌生.我刚刚完成了一个处理向量的章节,所以我对它们在现实世界中的使用有疑问(我是一名计算机科学专业的学生,所以我还没有太多真实的经验).
作者在每章末尾都有一个Q/A,其中一个是:
问:我应该何时使用向量而不是数组?
答:差不多总是如此.向量是高效和灵活的.它们确实比阵列需要更多的内存,但这种权衡几乎总是值得的.
你们有什么感想?我记得在Java书中学习过向量,但是在我的Comp totro中我们根本没有介绍它们.科学.上课,也不是我在大学的数据结构课.我也从未见过它们用于任何编程任务(Java和C).虽然我知道学校代码和现实世界的代码可能会有很大不同,但这让我觉得它们并没有被大量使用.
我不需要被告知两个数据结构之间的差异; 我非常了解他们.我想知道的是,如果作者在他的Q/A中给出了很好的建议,或者他只是想让初学者程序员免于破坏管理固定大小数据结构的复杂性.另外,不管你怎么想作者的意见,你怎么看在现实世界往往?
谢谢,
杰拉德
为另一个互联网论坛引用道歉,但我认为这很有趣,并想问:
如果你放弃编程语言的"安全"功能并避免像STL和Boost这样的东西,C++会更快.在原始字节到字节中,C++更快,但是C再也是如此.
当你添加STL的行李,Boost你比编写好的C#代码慢.C#JIT和Java jit的优点是这些安全功能得到了很好的优化.C++安全功能依赖于编译器的优化.
因此,如果您对STL和Boost代码不小心,那么您将拥有应用程序的跛脚.
我同意消除安全功能,但我看过很多高频工作广告,他们都要求Boost体验.当然,Boost对于生成快速代码不是一件坏事吗?或者这个人仅仅在理论上说明如果你只是在字节级操作它会更快?
编辑:引用是关于STL和Boost,因此我添加了STL标记.
我需要一个固定大小的元素数组,并调用它们需要知道它们如何放在内存中的函数,特别是:
这些函数glVertexPointer需要知道顶点的位置,它们彼此之间的距离等等.在我的例子中,顶点将是要存储的元素的成员.
为了得到这个数组中元素的索引,我宁愿避免index在我的元素中有一个字段,而是宁愿使用指针算术(即:Element *x将要的索引x - & array[0]) - 顺便说一句,这对我来说听起来很脏:是这是一种很好的做法还是我应该做些什么?
使用它是否安全std::vector?
有些东西让我觉得std::array更合适但是:
我的结构的构造函数和析构函数很少被调用:我不介意这样的开销.
我将把std::vector容量设置为我需要的大小(用于a的大小std::array,因此不会因为零星的重新分配而产生任何开销.
我不介意std::vector内部结构的空间开销.
我可以使用调整向量的大小(或更好:在安装过程中选择一个大小),我认为没有办法用std :: array做这个,因为它的大小是一个模板参数(这太糟糕了:我即使使用旧的类似C的数组,只需在堆上动态分配它就可以做到这一点.
如果std::vector对我的目的没问题,我想了解详细信息,如果它将有一些运行时开销std::array(或一个普通的C数组):
我知道一旦我增加它的大小,它将调用任何元素的默认构造函数(但我想如果我的数据有一个空的默认构造函数,这将不会花费任何费用?),对于析构函数也是如此.还要别的吗?
我正在为具有不同数据结构和技术(向量,数组和OpenMP)的矩阵实现C++乘法,我发现了一个奇怪的情况......我的动态数组版本运行得更好:
时间:
openmp mult_1:time:5.882000 s
array mult_2:time:1.478000 s
我的编译标志是:
/ usr/bin/g ++ -fopenmp -pthread -std = c ++ 1y -O3
C++矢量版
typedef std::vector<std::vector<float>> matrix_f;
void mult_1 (const matrix_f &  matrixOne, const matrix_f & matrixTwo, matrix_f & result) {
    const int matrixSize = (int)result.size();
    #pragma omp parallel for simd
    for (int rowResult = 0; rowResult < matrixSize; ++rowResult) {
        for (int colResult = 0; colResult < matrixSize; ++colResult) {
            for (int k = 0; k < matrixSize; ++k) {
                result[rowResult][colResult] += …我已经分析了c ++ vector和c-style数组之间的性能.结果有点出乎意料,因为文献说矢量的性能应该非常接近原始阵列,但事实并非如此.我在剖析中做错了什么?
void getVector1(int n)
{
    if (n < 0)
    {
        throw std::invalid_argument(std::string("negative argument n:") + std::to_string(n));
    }
    auto tp1 = std::chrono::steady_clock::now();
    std::vector<int> ivec(n);
    int i = 0;
    for (auto& x : ivec)
    {
        x = ++i;
    }
    auto tp2 = std::chrono::steady_clock::now();
    std::chrono::duration<double, std::micro> dd = tp2 - tp1;
    printf("spend %6.2f us time to create: %d elements vector inside %s() at %s:%d \n", dd.count(), n, __func__, __FILE__, __LINE__);
}
void getVector2(int n)
{
    if (n < 0)
    {
        throw …我刚尝试std::sort对两者std::vector<std::pair<float, unsigned int>>(填充push_back操作)和普通std::pair<float, unsigned int>> *数组(使用new分配然后逐个填充)进行基准测试.比较函数只比较了对的浮动部分.
令人惊讶的是,当在16M值上使用时,在std :: vector上它只需要大约1940毫秒,但在阵列上它大约是2190毫秒.谁能解释一下矢量怎么能更快?是由于缓存,还是只是std :: sort的数组版本实现不好?
gcc (GCC) 4.4.5 20110214 (Red Hat 4.4.5-6)
Intel(R) Core(TM) i7 CPU 870  @ 2.93GHz - cache size 8192 KB (计算机有两个四核CPU,但我认为排序只是单线程)
编辑:现在你可以叫我dumbass,但是当我试图重现我用于测量的代码时(我已经删除了原始代码)我无法重现结果 - 现在数组版本需要大约1915 + - 5ms(测量时间) 32次运行).我只能发誓我已经对10次测量进行了三次测试(手动)并得到了类似的结果,但这并不是一个严格的证据.
原始代码中可能存在一些错误,后台进程似乎无法进行,因为我已经交替测量了向量和数组版本,并且向量结果保持并且没有用户登录.
请将此问题视为已结束.谢谢你的努力.
我认为,使用示例更容易解释.让我们来一个模拟一级方程式赛车速度的课程,界面可能如下所示:
class SpeedF1
{
public:
  explicit SpeedF1(double speed);
  double getSpeed() const;
  void setSpeed(double newSpeed);
  //other stuff as unit 
private:
  double speed_;
};
现在,负速度在这种特殊情况下没有意义,也没有超过500 km/h的值.在这种情况下,如果提供的值不在逻辑范围内,则构造函数和setSpeed函数可能会抛出异常.
我可以引入一个额外的抽象层并插入一个额外的对象而不是double.新对象将是double的包装器,它将构造并永不修改.该类的接口将更改为:
class ReasonableSpeed
{
public:
  explicit ReasonableSpeed(double speed); //may throw a logic error
  double getSpeed() const;
  //no setter are provide
private:
  double speed_;
};
class SpeedF1
{
public:
  explicit SpeedF1(const ReasonableSpeed& speed);
  ReasonableSpeed getSpeed() const;
  void setSpeed(const ReasonableSpeed& newSpeed);
  //other stuff as unit 
private:
  ReasonableSpeed speed_;
};
使用这种设计SpeedF1不能抛出,但是每次我想重置速度时我需要额外支付一个对象构造函数.
对于有限的一组值是合理的类(例如日历中的月),我通常将构造函数设为私有,并提供一组完整的静态函数.在这种情况下,这是不可能的,另一种可能性是实现一个空对象模式,但我不确定它是否优于简单抛出异常.
最后,我的问题是:
解决此类问题的最佳做法是什么?