C/C++里一直有内联函数,很是羡慕.现在有了Flash builder4.7 beta 和 ASC2.0(Action Script Compiler是Flash builder 4.7 beta中内置的新版编译器),AS也能使用将函数内联了,真是大快人心. 内联函数 是将在函数被调用的地方使用替换成该函数实际的代码,这样就少了一次函数调用,也就少了很多地址查找,入栈出栈的操作,对于频繁调用的函数,就会有明显的性能提升.
函数成为内联函数必须同时满足的前提条件:
- The function is final, static or the containing scope is file or package
- 该函数是final,static的,或者该函数在在包或者文件(直接包含在文件内,而没有类)内
- The function does not contain any activations
- 该函数不能包含任何活动对象(Activation Object) (包括...参数和arguments对象)
- The function does not contain any try or with statements
- 该函数不能包含任意try catch 或 with语句
- The function does not contain any function closures
- 该函数不能包含任何函数闭包
- The function body contains less than 50 expressions
- 该函数体不超过50条语句
开启内联注意事项:
- 需要最新的flash builder 4.7 beta的ASC2.0来支持
- 需要-inline编译选项开启内联
- 需要[Inline]元数据使函数成为内联函数
- final 或 static的getter setter函数会自动成为内联函数,而不需要[Inline]元数据
内联示例
package
{
import flash.display.Sprite;
public class InlineTest extends Sprite
{
private var _m:int = 0;
private static var _s:int = 0;
public function InlineTest()
{
trace(m); // inlined
m = 5; //inlined
InlineTest.s = 7; //inlined
f0(0); //inlined
f1(0); // not-inlined, 因为f1包含一条try语句
}
// 自动inline作为final getter, 而不必使用Inline元数据
final public function get m():int
{
return _m;
}
// 自动inline作为final setter, 而不必使用Inline元数据
final public function set m(m:int):void
{
if (m < 0)
_m = m;
else
_m = 0;
}
// 自动inline作为static getter, 而不必使用Inline元数据
static public function get s():int
{
return _s;
}
// 自动inline作为static setter, 而不必使用Inline元数据
static public function set s(s:int):void
{
_s = s;
}
// 使用Inline元数据 内联final函数
[Inline]
final public function f0(p:int):int
{
var v:int = p + _m;
return v;
}
// 不能使用Inline元数据内联包含try语句的方法
//[Inline]
final public function f1(p:int):int
{
try {
return p + _m;
} finally
{
return 0;
}
}
}
}
bug
类中Inline的函数在类的外部调用时也展开了而不是当做普通函数调用.有两种情况可以解决这个问题.
- 在类的外部调用类中定义的inline的函数时,统一当做普通函数调用
- 在类的外部调用类中定义的inline的函数时,仅将函数体内调用了非public的方法或属性时当做普通函数调用
第一种情况是比较容易实现的,这也是gcc编译c++时使用的方法.而第二种相对复杂些,但是会带来更高的效率.
当前ASC2.0对inline的bug示例
package
{
import flash.display.Sprite;
public class InlineTest2 extends Sprite
{
public function InlineTest2()
{
//编译后会变成
//var _local1 = A;
//A._s;
//这里_s是A的private变量,但是也直接访问了.
//这里应该不使用内联.而是方法调用
A.getS();
}
}
}
class A
{
private static var _s:int = 1;
[Inline]
static public function getS():int { return _s; }
}
2012年12月19日更新: 在release版本里用命名空间的方法修复了这个bug,不过通过反编译发现多用inline可以提高破解难度。
» 转载请注明来源:www.litefeel.com » 《ASC2.0让AS也可以写inline函数》
» 本文链接地址:https://www.litefeel.com/as-inline/
» 订阅本站:www.litefeel.com/feed/
» Host on Linode VPS
» 本文链接地址:https://www.litefeel.com/as-inline/
» 订阅本站:www.litefeel.com/feed/
» Host on Linode VPS
This post was last modified on 2019 年 03 月 04 日 00:29