这是一个相当古老的话题:主持人和吸气者是好还是坏?
我的问题是:C++/D/Java中的编译器是否内联getter和setter?
与直接字段访问相比,getter/setter在多大程度上影响性能(函数调用,堆栈帧).除了使用它们的所有其他原因之外,我想知道除了是一个好的OOP练习之外它们是否应该影响性能.
jal*_*alf 24
这取决于.没有普遍的答案总是如此.
在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_;
}
Run Code Online (Sandbox Code Playgroud)
如果函数的定义对类的用户不可见(包括foo.h,但不会看到foo.cpp),那么编译器可能无法内联函数调用.
如果启用链接时代码生成作为优化,MSVC应该能够内联它.我不知道海湾合作委员会如何处理这个问题.
通过扩展,这也意味着如果getter是在不同的.dll/.so中定义的,则无法内联调用.
在任何情况下,我认为琐碎的获取/制定者不一定是"良好的OOP实践",或者"存在使用它们的所有其他原因".很多人认为琐碎的获取/制定者1)是设计糟糕的标志,2)浪费打字.
就个人而言,这不是我对任何一种方式都有所了解的事情.对我而言,对于有资格作为"良好的OOP实践"的东西,它必须具有一些可量化的积极效果.琐碎的获取/制定者有一些边缘优势,有些也是微不足道的缺点.因此,我不认为他们是好的或坏的做法.如果你真的想要,他们只是你可以做的事情.
在D中,所有类的方法,但不是结构,默认是虚拟的.您可以通过使方法或整个类最终来使方法非虚拟.此外,D具有属性语法,允许您创建公共字段,然后在不破坏源级兼容性的情况下将其更改为getter/setter.因此,在DI中建议只使用公共字段,除非您有充分的理由不这样做.如果你想出于某种原因使用琐碎的getter/setter,比如只有一个getter并让这个变量从类外部变为只读,那就把它们作为final.
编辑:例如,行:
S s;
s.foo = s.bar + 1;
Run Code Online (Sandbox Code Playgroud)
对两者都有用
struct S
{
int foo;
int bar;
}
Run Code Online (Sandbox Code Playgroud)
和
struct S
{
void foo(int) { ... }
int bar() { ... return something; }
}
Run Code Online (Sandbox Code Playgroud)
我有一次完全相同的问题.
为了回答它,我编写了两个小程序:
首先:
#include <iostream>
class Test
{
int a;
};
int main()
{
Test var;
var.a = 4;
std::cout << var.a << std::endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
第二:
#include <iostream>
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;
}
Run Code Online (Sandbox Code Playgroud)
我将它们编译为汇编程序,使用-O3(完全优化)并比较两个文件.他们是相同的.没有优化他们是不同的.
这是在g ++下.那么,回答你的问题:编译器可以轻松优化getter和setter.
小智 6
我在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());
}
}
Run Code Online (Sandbox Code Playgroud)
我知道,最后鲍勃比我大一点,但为此,它应该没问题.
| 归档时间: |
|
| 查看次数: |
11754 次 |
| 最近记录: |