您的位置:首页 > 编程语言 > Java开发

Java如何得到某一天是星期几

2007-07-22 17:02 211 查看
内联函数像函数,但是却省下了调用函数的时空开销。但实际上,编译器做的不止于此。因为编译器的优化一般是针对一整块没有函数调用的代码,所以,如果你使用了内联函数,编译器也许会根据上下文再优化一下内联函数的函数体。

使用内联函数的代价:会使目标文件变大;由此也更耗内存;太多的内联函数导致内存分页过多;最后因频繁的页面交换降低CPU的缓存利用。但是,当内联函数非常短的时候,目标文件反而变小;最后反而提高了CPU的缓存利用率。

关键字inline只是对编译器的一个请求,而非命令。编译器有可能不理会这个请求。

隐式的内联函数请求,就是把函数体放到类的定义里:

class Person
{
public:
...
int age() const { return theAge; }    // an implicit inline request
private:
int theAge;
};


显式的内联函数请求,就是使用了inline关键字:

template<typename T>								// an explicit inline
inline const T& std::max(const T& a, const T& b)	// request: std::max is
{
return a < b ? b : a;							// preceded by "inline"
}


上面这个max既是内联函数,又是模板函数,而且都定义在头文件里。由此许多程序员认为,模板函数必须是内联的。

这个结论错误,而且有害。

内联函数要放在头文件里。因为大多数编译环境在编译时处理内联。它们要搜索头文件,找到内联函数的定义,然后在调用的地方用函数体去做替换工作。

(少数编译器在链接时做内联工作,基于.Net CLI的托管环境甚至在运行时做内联的工作。这是C++世界的例外,不予考虑。)

模板要放在头文件里。因为编译器也要知道定义才能在编译时做模板实例化。(也有例外。)

但是,模板和内联完全不相关。写模板的时候,需要内联的时候才内联(无论隐式还是显式)。

编译器看到复杂的函数时不会内联它:有循环的、有递归的、有虚函数调用的。用-Winline可以让编译器在忽略一个内联请求时发出一个警告。

编译器对使用函数指针做的函数调用不做内联处理。

inline void f() {...}	// assume compilers are willing to inline calls to f
void (*pf)() = f;		// pf points to f
...
f();					// this call will be inlined, because it's a "normal" call
pf();					// this call probably won't be, because it's through a function pointer


有时,即使你不用函数指针,有的内联函数也不做内联处理。因为有的函数指针是隐形的。

class Base
{
public:
...
private:
std::string bm1, bm2;               // base members 1 and 2
};
class Derived: public Base
{
public:
Derived() {}                         // Derived's ctor is empty — or is it?
...
private:
std::string dm1, dm2, dm3;           // derived members 1–3
};


看那个Derived::ctor,空的,但不能内联。因为一个类的new和delete会发生很多事。C++规定了必须做这些事,然后编译器的实现者们就会让编译器自动在你的程

序中插入各种各样的代码。由此导致ctor不是看上去那么空。

基类的ctor也不能内联,否则会大大影响程序。

库函数内联的话会影响它以后的升级。去掉内联,升级的时候只是重新链接的问题,不会影响编译,不会影响客户的代码。

很多debugger对内联支持不好。

和inline有关的GCC开关

>>> -fno-inline

忽略所有inline关键字。

>>> -finline-functions

内联所有简单函数。如果该简单函数是static的,那么就不生成汇编码。该选项在-O3时自动启用。

>>> -finline-functions-called-once

所有只调用一次的static函数都做内联处理,即使没有inline关键字。不生成汇编码。该选项在启用-funit-at-a-time时自动启用。

>>> -fearly-inlining

有always_inline标志的函数、非常小的函数都在-fprofile-generate之前做内联处理。该选项默认是开启的。

>>> -finline-limit=n

GCC说内联函数的限制是n=600。

>>> -fkeep-inline-functions

在C程序里,如果内联函数是static的,则编译该函数到目标文件中;在C++程序里,所有内联函数都编译到目标文件里。

>>> -fno-default-inline

在函数体内定义的函数不做内联处理。

>>> -fno-implement-inlines

>>> -fno-implicit-inline-templates
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: