2010-03-28 27 views
9

Objective-C'nin C++ veya "g ++ -fast" etiketindeki gibi sık kullanılan yöntemlerin satırları boyunca daha hızlı yürütülmesini sağlamak için standart optimizasyon numaraları var mı?Objective-C optimizasyonu

Düzenleme: Herhangi bir giriş için iki (veya daha fazla) tamsayı olduğunda, herhangi birinin SEL ve IMP kullanarak kısa bir örneği var mı?

+0

Bu konu burada ayrıntılı olarak ele alınmıştır: Kakao gibi üst düzey bir çerçevede http://www.mulle-kybernetik.com/artikel/Optimization/ – codewarrior

+1

, bu gibi en küçük optimizasyonlar zaman kaybı vardır (birçok derleyici ayarından farklı olarak), birçok temel sınıf zaten ağır bir şekilde optimize edilmiştir. Sadece profil bir şey fazladan zaman alıyorsa gösterir. – shosti

cevap

12

Gerçekleştirmek için yeterli zamana değmeyecek küçük bir optimizasyon ve kişisel olarak hiç kullanmadığım ama hala bilmem gereken iyi bir optimizasyon. Aynı mesajı tekrar tekrar aynı nesneye göndermek yerine, doğrudan yöntem uygulamasını kullanarak tekrarlanan yöntem gönderimini devre dışı bırakabilirsiniz. Yerine Örnek:

for (int i = 0; i < 100000000; i++) 
    [someObject messageWithInt:i]; 

Sen deneyebilirsiniz:

SEL theSelector = @selector(messageWithInt:); 
IMP theMethod = [someObject methodForSelector:theSelector]; 

for (int i = 0; i < 100000000; i++) 
    theMethod (someObject, theSelector, i); 

Bu yöntem araması yalnızca bir kez yapılır anlamına gelir ve geri IMP değeri üzerinden doğrudan yöntemi çağırabilirsiniz. Tüm Objective-C yöntemi uygulamalarının en az iki argümanı vardır, ilk argüman id tipinin alıcı nesnesi olup, metot uygulaması içinde self olur ve ikinci argüman metodu belirlemek için kullanılan [SEL tipinde] seçicidir. uygulama ve yöntem uygulamasında _cmd olur.

“ işlev tanımını (” doğru ifadesini hatırlayamıyorum) kullanmazsanız, bu yaklaşım hızla ekşitirebilir. IMP, void* döndüren bir işlev için typedef ve bağımsız değişken olarak (id,SEL,...) alır. Bu yöntem aslında float gibi başka bir şey döndürürse, kullanımı zahmetli hale getirebilir. Bu madde ile yardımcı olmak için, bu gibi -methodForSelector: dönüş değer dağıtmak yapabilirsiniz: theMethod kaydedebilir, bazı bakım ile

typedef float (*MyMethodIMP)(id,SEL,int); 

SEL theSel = @selector(messageWithInt:); 
MyMethodIMP theMethod = (MyMethodIMP)[someObject methodForSelector:theSel]; 
float result = 0.0; 

for (int i = 0; i < 100000000; i++) 
    result += theMethod (someObject, theSel, i); 

ve belirli bir sınıfın tüm örnekleri için kullanmak mümkün olabilir, sadece bir örnek değil, dikkatli bir şekilde bas.

+6

Çoğu performans öğesinde olduğu gibi, darboğazların nerede olduğunu görmek için kodunuzdaki Aygıtları çalıştırmalısınız. Yukarıdaki öğeler harika ... eğer onlara ihtiyacınız varsa. Yapmazsan, kodu okumak zor oluyor. – nall

+2

@nall: Kesinlikle. Basit bir kıyaslama yaptım ve yukarıdaki gibi sıkı döngüler halinde, gönderimi atlamak, yürütme süresinin yaklaşık yarısında sonuçlandı ('TheMethod' bazı temel matematikler yaptı). Eğer 'objc_msgSend' içinde çok fazla zaman harcanırsa (ya da bu günlerde yöntem denirse), bu durumda gönderimi atlamak bir seçenek olabilir, aksi taktirde, bir optimizasyondan ziyade bir saptırma olacaktır. – dreamlax

+0

Gerçekten ilginç bir optimizasyon, ancak IMP'yi bir yöntemden almak yerine C işlevi yapmak daha kolay olmaz mıydı? – shosti

9

Optimizasyon en iyi derleyici tarafından ele alınır. Mac'ler GCC'yi kullanır, bu yüzden standart optimizasyon GCC bayrağı (-0 seviye) çalışmalıdır. XCode'da, en iyileştirme düzeyini project settings'da ayarlayabilirsiniz. GCC'yi kullanmıyorsanız, optimizasyonun nasıl etkinleştirileceğini öğrenmek için derleyici belgelerini kontrol edin.

Güncelleme: XCode 4 varsayılan olarak LLVM arka ucunu kullanır. Hem GCC hem de clang cepheleri, "-0 n" optimizasyon bayraklarını kullanır. GCC için n, 0 ile 3 arasında bir tamsayı veya "s" veya (yalnızca Apple) "z" şeklindedir. Clang için, n, 0 ila 4 veya "s" arasında bir tamsayıdır.

+0

Bu doğru - kapalı bellek [-O3] – SK9

+0

olarak ayarlanmıştır Çok teşekkürler tüm önerileriniz ve zamanınız için! Eğer istekliyseniz, Method giriş olarak iki (veya daha fazla) tam sayı aldığında, SEL ve IMP'yi kullanarak kısa bir örnek verebilir misiniz? – SK9

+0

@SpecialK: kısa bir örnek * ne *? Dreamlax'ın cevabı hakkında yorum yapmak mı istediniz? – outis