ECMAScript 런타임 용 JSON 코드를 연마하고 실험을하기로 결정했습니다. 다음 str
함수에는 4 개의 논리적 단계가 있습니다.이 단계를 함수로 분해하고 인라인으로 표시했습니다.인라인 수정자를 남용하고 있습니까?
and private str (state:StringifyState) (key:string) (holder:IObject) : IDynamic =
let inline fourth (value:IDynamic) =
match value.TypeCode with
| LanguageTypeCode.Null ->
state.environment.CreateString "null" :> IDynamic
| LanguageTypeCode.Boolean ->
let v = value :?> IBoolean
state.environment.CreateString (if v.BaseValue then "true" else "false") :> IDynamic
| LanguageTypeCode.String ->
let v = value :?> IString
state.environment.CreateString (quote v.BaseValue) :> IDynamic
| LanguageTypeCode.Number ->
let v = value :?> INumber
if not (Double.IsInfinity(v.BaseValue))
then v.ConvertToString() :> IDynamic
else state.environment.CreateString "null" :> IDynamic
| LanguageTypeCode.Object ->
let v = value :?> IObject
let v = if v.Class = "Array" then ja state v else jo state v
state.environment.CreateString v :> IDynamic
| _ ->
state.environment.Undefined :> IDynamic
let inline third (value:IDynamic) =
match value.TypeCode with
| LanguageTypeCode.Object ->
let v = value :?> IObject
match v.Class with
| "Number" ->
fourth (v.ConvertToNumber())
| "String" ->
fourth (v.ConvertToString())
| "Boolean" ->
fourth (v.ConvertToBoolean())
| _ ->
fourth value
| _ ->
fourth value
let inline second (value:IDynamic) =
match state.replacerFunction with
| :? ICallable as f ->
let args = state.environment.CreateArgs ([| state.environment.CreateString key :> IDynamic; value |])
let value = f.Call (state.environment, holder :> IDynamic, args)
third value
| _ ->
third value
let inline first (value:IDynamic) =
match value with
| :? IObject as v ->
let toJSON = v.Get "toJSON"
match toJSON with
| :? ICallable as f ->
let args = state.environment.CreateArgs ([| state.environment.CreateString key :> IDynamic |])
let value = f.Call (state.environment, value, args)
second value
| _ ->
second value
| _ ->
second value
first (holder.Get key)
전체 최적화로 컴파일하고 반사경을 사용하여 결과 어셈블리를 열어 결과를 확인합니다.
[CompilationArgumentCounts(new int[] { 1, 1, 1 })]
internal static IDynamic str(StringifyState state, string key, IObject holder)
{
IObject obj3;
ICallable callable;
ICallable callable2;
IArgs args;
IDynamic dynamic3;
IDynamic dynamic4;
ICallable callable3;
IDynamic dynamic5;
IBoolean flag;
IString str;
INumber number;
IObject obj4;
string str2;
INumber number2;
IObject obj5;
string str3;
IString str4;
IBoolean flag2;
IDynamic thisBinding = holder.Get(key);
IObject obj2 = thisBinding as IObject;
if (obj2 == null)
{
callable = [email protected] as ICallable;
if (callable == null)
{
switch (thisBinding.TypeCode)
{
case LanguageTypeCode.Object:
obj3 = (IObject) thisBinding;
str2 = obj3.Class;
if (!string.Equals(str2, "Number"))
{
if (string.Equals(str2, "String"))
{
dynamic3 = obj3.ConvertToString();
switch (dynamic3.TypeCode)
{
case LanguageTypeCode.Null:
return (IDynamic) [email protected]("null");
case LanguageTypeCode.Boolean:
flag = (IBoolean) dynamic3;
return (IDynamic) [email protected](!flag.BaseValue ? "false" : "true");
case LanguageTypeCode.String:
str4 = (IString) dynamic3;
return (IDynamic) [email protected](quote(str4.BaseValue));
case LanguageTypeCode.Number:
number = (INumber) dynamic3;
if (double.IsInfinity(number.BaseValue))
{
return (IDynamic) [email protected]("null");
}
return (IDynamic) number.ConvertToString();
// ... I removed a large amount of code.
return (IDynamic) [email protected];
}
분명히 inline
수식어는 꽤 리터럴입니다. 코드는 매우 거대하며 일부 예비 테스트는 매우 효율적입니다. 결과 어셈블리의 크기에 신경 쓰지 않으면 모든 함수를 인라인으로 던지십시오. inline
의 사용이 적절한 지 알 수있는 지침은 무엇입니까? 가능한 경우 매번 성능을 측정하지 않아도되도록하고 싶습니다.
"초안 F # 부품 설계 지침 (2010 년 8 월)"을 읽었습니까? http://research.microsoft.com/en-us/um/cambridge/projects/fsharp/manual/fsharp-component-design-guidelines.pdf –
중복 가능성? : F #에서'inline' 사용 : http : // stackoverflow.com/questions/3754862/use-of-inline-in-f ?? –
@Mitch - 가능한 한 내 질문이 원래 생각했던 것만 큼 소리가 나지 않을 수도 있지만 링크 된 것과 다른 초점이 있다고 느낍니다. – ChaosPandion