2011-11-19 12 views
13
  1. Czy LLVM automatycznie konwertuje metody Objective-C na funkcje śródliniowe, jeśli jest to możliwe?Czy LLVM konwertuje metody Objective-C na funkcje wbudowane?

    (czyli jest to tak samo wydajnych stworzyć metodę Objective-C dla bloku kodu, który można wkleić inline inaczej?)

  2. Jeśli LLVM nie wykonuje tej optymalizacji, to dlaczego nie? Jeśli tak, (a) czy są jakieś ustawienia kompilacji, które muszę ustawić, aby tak się stało? (b) Jak mogę stwierdzić, czy metoda Objective-C będzie inline?

Odpowiedz

12

Nie, ponieważ nie można go poznać w kontekście środowiska uruchomieniowego Obj-C, jeśli można przeprowadzić takie optymalizacje. Należy pamiętać, że metody Obj-C są wywoływane przez wysyłanie wiadomości, wiadomości te mogą pochodzić z więcej niż tylko składni [myObject doSomething].

Rozważ [obj performSelector:NSSelectorFromString(@"hello")] fakt, że może się tak zdarzyć, oznacza, że ​​niemożliwe byłoby kiedykolwiek wstawienie jakiejkolwiek metody.

Istnieje również łańcuch zdarzeń, który występuje, gdy wiadomość zostanie odebrana przez klasę, zdarzenia te mogą przekierować, a nawet zmienić wysyłaną wiadomość. Dzieje się to w sposób przejrzysty pod przesłaniem wiadomości.

+0

Dlaczego LLVM nie może zastąpić zwykłych połączeń, np. '[Obj x]; Wywołania obj.x' i 'performSelector', np.' [obj performSelector: x_sel] ', itp., z treścią metody' x'? I dlaczego nie może sprawdzić implementacji metod takich jak 'forwardInvocation:', aby określić, czy powinien on wstawiać? C'mon LLVM, bądź sprytniejszy! :) – ma11hew28

+7

Ponieważ mogą być wymieniane w czasie wykonywania trywialnie. Mogę zmienić impendę dowolnej metody w 3 lub 4 liniach kodu środowiska wykonawczego. –

9

nr Istotną cechą Objective-C, która wiadomość wysyłka (należy pamiętać, że w Obj-C wysłać wiadomość, nie wywołać metodę) dzieje się dynamicznie w czasie wykonywania, a nie w czasie kompilacji czas.

Z tego powodu wysyłanie komunikatów w Obj-C zawsze będzie trwać nieco wolniej niż zwykłe wywołanie funkcji (nawet jeśli funkcja nie jest wstawiona).

9

Załóżmy na chwilę, że kompilator inlines metodę:

@implementation AwesomeClass 

- (void)doFoo OBJC_INLINE { // or some way to indicate "this is an inline method" 
    NSLog(@"doing foo!"); 
} 

- (void)doBar { 
    [self doAwesomeStuff]; 
    [self doFoo]; 
} 

@end 

tak że -doBar zasadniczo postać:

- (void)doBar { 
    [self doAwesomeStuff]; 
    { 
    NSLog(@"doing foo!"); 
    } 
} 

niesamowite, że wydaje się, że byłoby szybciej, prawda? Zapisujemy sobie całe tuziny instrukcji, nie wywołując objc_msgSend. Więc spakuj to i opublikuj jako plik .a.

NSCleverCoder przychodzi i mówi „ale chcę doFoo zrobić trochę więcej”, tak robi:

@interface SuperAwesomeClass : AwesomeClass @end 
@implementation SuperAwesomeClass 
- (void)doFoo { 
    NSLog(@"doing more foo!"); 
    [super doFoo]; 
} 
@end 

Kiedy próbuje uruchomić to, nigdy nie jest wywoływana, ponieważ AwesomeClass nigdy faktycznie wywołuje metodę -doFoo.

"Ale", mówisz, "to jest wymyślny przykład!"

Nie, nie jest. W Objective-C jest to całkowicie legalne w dowolnym momencie tworzenia lub wykonywania aplikacji. Mogę to zrobić, pisząc kod. Heck, mogę nawet zrobić to w czasie wykonywania, używając objc_allocateClassPair i class_addMethod, aby dynamicznie utworzyć podklasę i dodać nadpisanie metody.

Potrafię również implementować metody metody swizzle.Nie podoba ci się istniejąca implementacja -doFoo? To super; Zamień go na swój własny. Zaczekaj; jeśli metoda została wstawiona, twoja nowa implementacja nigdy nie zostanie wywołana, ponieważ -doBar nigdy nie wywołuje metody -doFoo.

Mogłem zobaczyć, że jest to możliwe, jeśli istnieje jakiś sposób opisania metody jako nieprzykrywalnej. But there's no way to do that, więc problem jest dyskusyjny. I nawet wtedy, nadal byłby to zły pomysł; tylko dlatego, że kompilator nie pozwala ci to zrobić, nie oznacza, że ​​nie możesz wciąż pracować nad nim w czasie wykonywania. Znowu natkniesz się na problemy.

+0

Sądzę, że po prostu myślałem, że kompilator może wykryć takie przypadki, w których metoda jest wywoływana w ramach przesłoniętej metody, a także wstawić ją do nadrzędnej metody ... Ale widzę, jak kompilator musiałby być bardzo cienki i inteligentny Zrób to. Nadal ... ARC jest całkiem niesamowite ... Może mogliby dodać kolejną fajną funkcję do LLVM, która wie, jak wbudować metody. – ma11hew28

Powiązane problemy