当前位置:  开发笔记 > 编程语言 > 正文

getter和setter是否会影响C++/D/Java的性能?

如何解决《getter和setter是否会影响C++/D/Java的性能?》经验,为你挑选了4个好方法。

这是一个相当古老的话题:主持人和吸气者是好还是坏?

我的问题是:C++/D/Java中的编译器是否内联getter和setter?

与直接字段访问相比,getter/setter在多大程度上影响性能(函数调用,堆栈帧).除了使用它们的所有其他原因之外,我想知道除了是一个好的OOP练习之外它们是否应该影响性能.



1> jalf..:

这取决于.没有普遍的答案总是如此.

在Java中,JIT编译器可能迟早会内联它.据我所知,JVM JIT编译器只优化频繁使用的代码,因此最初可以看到函数调用开销,直到经常充分调用getter/setter.

在C++中,它几乎肯定会内联(假设启用了优化).但是,有一种情况可能不会:

// foo.h
class Foo {
private:
  int bar_;

public:
  int bar(); // getter
};

// foo.cpp
#include "foo.h"

int Foo::bar(){
  return bar_;
}

如果函数的定义对类的用户不可见(包括foo.h,但不会看到foo.cpp),那么编译器可能无法内联函数调用.

如果启用链接时代码生成作为优化,MSVC应该能够内联它.我不知道海湾合作委员会如何处理这个问题.

通过扩展,这也意味着如果getter是在不同的.dll/.so中定义的,无法内联调用.

在任何情况下,我认为琐碎的获取/制定者不一定是"良好的OOP实践",或者"存在使用它们的所有其他原因".很多人认为琐碎的获取/制定者1)是设计糟糕的标志,2)浪费打字.

就个人而言,这不是我对任何一种方式都有所了解的事情.对我而言,对于有资格作为"良好的OOP实践"的东西,它必须具有一些可量化的积极效果.琐碎的获取/制定者有一些边缘优势,有些也是微不足道的缺点.因此,我不认为他们是好的或坏的做法.如果你真的想要,他们只是你可以做的事情.



2> dsimcha..:

在D中,所有类的方法,但不是结构,默认是虚拟的.您可以通过使方法或整个类最终来使方法非虚拟.此外,D具有属性语法,允许您创建公共字段,然后在不破坏源级兼容性的情况下将其更改为getter/setter.因此,在DI中建议只使用公共字段,除非您有充分的理由不这样做.如果你想出于某种原因使用琐碎的getter/setter,比如只有一个getter并让这个变量从类外部变为只读,那就把它们作为final.


编辑:例如,行:

S s;
s.foo = s.bar + 1;

对两者都有用

struct S
{
     int foo;
     int bar;
}

struct S
{
     void foo(int) { ... }
     int bar() { ... return something; }
}


它实际上并没有得到支持.基本上,如果你有一个int setFoo(int)你可以像setFoo = 4;那样调用它,你可以省略无参数函数调用的括号; 但是你不能使用更复杂的运算符,比如++和+ =.
关于虚拟:使方法非虚拟的另一种方法是将"void foo()"更改为void foo()()".这使得它成为一个模板化方法,不接受模板参数,也可以隐式实例化.模板是从不虚拟.

3> Marenz..:

我有一次完全相同的问题.

为了回答它,我编写了两个小程序:

首先:

#include 

class Test
{
     int a;
};

int main()
{
    Test var;

    var.a = 4;
    std::cout << var.a << std::endl;
    return 0;
}

第二:

#include 

class Test
{
     int a;
     int getA() { return a; }
     void setA(int a_) { a=a_; }
};

int main()
{
    Test var;

    var.setA(4);
    std::cout << var.getA() << std::endl;
    return 0;
}

我将它们编译为汇编程序,使用-O3(完全优化)并比较两个文件.他们是相同的.没有优化他们是不同的.

这是在g ++下.那么,回答你的问题:编译器可以轻松优化getter和setter.



4> 小智..:

我在Java中尝试过:使用和不使用getter和setter都是一样的.结果:两个版本的执行时间没有显着差异.这是代码:

class Person
{
    public int age;
    String name;
    public Person(String name,int age)
    {
        this.name=name;
        this.age=age;   
    }

}
class GetSetPerson
{
    private int age;
    String name;
    public GetSetPerson(String name,int age)
    {
        this.name=name;
        this.age=age;   
    }
    public void setAge(int newage)
    {
        age=newage;
    }
    public int getAge()
    {
    return age; 
    }
}
class Proba
{
//Math.hypot kb 10-szer lassabb, mint a Math.sqrt(x*xy*y)!!!

public static void main(String args[])
{
long startTime, endTime, time;
int i;int agevar;
//Person p1=new Person("Bob",21);
GetSetPerson p1=new GetSetPerson("Bob",21);
startTime=System.nanoTime();
/*
for (i=0;i<1000000000;i++)
     {
     p1.age++;

     }

*/    
for (i=0;i<1000000000;i++)
     {
     agevar=p1.getAge();
     agevar++;
     p1.setAge(agevar);
     }

endTime=System.nanoTime();
time=endTime-startTime;
System.out.println(""+time);
System.out.println(p1.name+"'s age now  is "+p1.getAge());
}

}

我知道,最后鲍勃比我大一点,但为此,它应该没问题.

推荐阅读
帆侮听我悄悄说星星
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有