Swift, bu karşılaştırmalarda Objective-C'den çok daha hızlı nasıl olabilir?


115

Apple , WWDC14'te yeni programlama dili Swift'i başlattı . Sunumda, Objective-C ve Python arasında bazı performans karşılaştırmaları yaptılar. Aşağıdakiler, slaytlarından birinin, bazı karmaşık nesne sıralamasını yapan bu üç dilin karşılaştırılmasının bir resmidir:

görüntü tanımını buraya girin

RC4 şifreleme algoritmasını kullanarak performans karşılaştırması hakkında daha inanılmaz bir grafik vardı .

Açıkçası, bu bir pazarlama konuşması ve bunun her birinde nasıl uygulandığına dair detaylara girmediler. Yine de merak etmemi sağladım:

  1. Yeni bir programlama dili nasıl bu kadar hızlı olabilir?
  2. Objective-C sonuçları kötü bir derleyiciden kaynaklanıyor mu yoksa Objective-C'de Swift'den daha az etkili bir şey var mı?
  3. % 40'lık bir performans artışını nasıl açıklarsınız? Çöp toplama / otomatik referans kontrolünün bazı ek masraflar getirebileceğini biliyorum, ama bu kadar mı?

13
@MathewFoscarini Obj-C assembler'a gidiyor ama pahalı bir nesne mesaj gönderme mekanizması var. Önemli olmayan çoğu GUI çalışması için, ancak sıralaması için çok önemlidir.
Donal Fellows

17
Python ile karşılaştırmak buradaki asıl tırmalayıcıdır.
asthasr

9
@ psion pazarlama ve dil python sözdiziminden (golang gibi) ödünç gibi görünüyor. "Hey, python geliştiricileri,

4
@MichaelT Anladım, ama hala garip. Dillerle ilgili bir şey bilen bir kimse, tercüme edilmiş bir dil olarak Python'un yalnızca Objective-C veya diğer derlenmiş diller ile aynı oyun parkında olmayacağını fark edecektir (çoğu görev için). Bir kriter olarak kullanmak garip.
Asthasr

7
Muhtemelen kodu yazmak için
Lukas Eder

Yanıtlar:


62

İlk olarak, (IMO) Python ile karşılaştırmak neredeyse anlamsız. Yalnızca Objective-C ile karşılaştırma yapmak anlamlıdır.

  • Yeni bir programlama dili nasıl bu kadar hızlı olabilir?

Amaç-C yavaş bir dildir. (Sadece C kısmı hızlıdır, fakat bunun nedeni C'dir) Hiç bu kadar hızlı olmamıştı. Onların (Apple'ın) amacı için yeterince hızlıydı ve eski sürümlerinden daha hızlıydı. Ve yavaştı çünkü ...

  • Objective-C kötü bir derleyiciden mi kaynaklanıyor veya Objective-C'de Swift'den daha az etkili bir şey var mı?

Objective-C, dinamik olarak gönderilecek her yöntemin garantilidir. Hiçbir statik gönderim yok. Bu, bir Objective-C programını daha da optimize etmeyi imkansız hale getirdi. Eh, belki JIT teknolojisi biraz yardımcı olabilir, ancak Apple AFAIK, öngörülemeyen performans özelliklerinden ve nesne ömründen gerçekten nefret ediyor. JIT olayı kabul ettiklerini sanmıyorum. Objective-C uyumluluğu için bazı özel nitelikler koymadığınız sürece Swift, böyle dinamik gönderim garantisine sahip değildir.

  • % 40'lık bir performans artışını nasıl açıklarsınız? Çöp toplama / otomatik referans kontrolünün bazı ek masraflar getirebileceğini biliyorum, ama bu kadar mı?

GC veya RC burada önemli değil. Swift ayrıca öncelikle RC kullanıyor. Orada hiçbir GC yoktur ve GC teknolojisinde devasa bir mimari sıçrama olmadıkça da olmayacaktır. (IMO, sonsuza kadar) Swift'in statik optimizasyon için daha fazla boşluğu olduğuna inanıyorum. Özellikle düşük seviyeli şifreleme algoritmaları, genellikle çok büyük sayısal hesaplamalara dayanırlar ve bu, statik olarak gönderilen diller için büyük bir kazançtır.

Aslında şaşırdım çünkü% 40 çok küçük görünüyor. Daha fazlasını beklerdim. Her neyse, bu ilk sürüm, ve optimizasyonun ana sorun olmadığını düşünüyorum. Swift bile özellik tamamlanmış değil! Daha iyi yapacaklar.

Güncelleme

Bazıları GC teknolojisinin üstün olduğunu savunmam için beni rahatsız ediyor. Aşağıdaki şeyler tartışılabilir olabilir ve sadece çok taraflı görüşüm olsa da, bu gereksiz argümandan kaçınmam gerektiğini söylemeliyim.

Muhafazakar / iz / nesiller / artan / paralel / gerçek zamanlı GC'lerin ne olduğunu ve nasıl farklı olduklarını biliyorum. Bence okuyucuların çoğu da zaten bunu biliyor. GC'nin bazı alanlarda çok iyi olduğunu ve bazı durumlarda yüksek verim gösterdiğini de kabul ediyorum.

Her neyse, GC işlem hacminin her zaman RC'den daha iyi olduğunu iddia ediyorum. RC genel giderinin çoğu ref-count sayı değişkenini korumak için ref-sayma işleminden ve kilitlemeden gelir. Ve RC uygulaması genellikle sayım işlemlerini önlemek için bir yol sağlar. Objective-C'de orada __unsafe_unretainedve Swift'de (yine de bana göre hala belirsiz olsa da) bazı şeyler var unowned. Eğer geri sayım işleminin maliyeti kabul edilemez ise, mekaniği kullanarak seçmeli olarak kapsam dışı bırakmayı deneyebilirsiniz. Teorik olarak, RC ek yükünü önlemek için tutmayan referansları çok agresif bir şekilde kullanarak neredeyse benzersiz mülkiyet senaryosunu taklit edebiliriz. Ayrıca, derleyicinin bazı gereksiz gereksiz işlemleri otomatik olarak ortadan kaldırabileceğini de umuyorum.

RC sisteminden farklı olarak, AFAIK, referans tiplerinin kısmi kapsam dışı bırakılması GC sisteminde bir seçenek değildir.

GC tabanlı sistemi kullanan birçok yayınlanmış grafik ve oyun olduğunu biliyorum ve aynı zamanda çoğunun determinizm eksikliği yüzünden acı çektiğini biliyorum. Sadece performans özelliği için değil, aynı zamanda ömür boyu yönetimi için de geçerlidir. Birlik çoğunlukla C ++ dilinde yazılmıştır, ancak küçük C # kısmı tüm garip performans sorunlarına neden olur. HTML hibrit uygulamaları ve hala herhangi bir sistemde öngörülemeyen ani acı çekiyor. Yaygın olarak kullanılması, bunun üstün olduğu anlamına gelmez. Bu, fazla seçeneği olmayan insanlar için kolay ve popüler olduğu anlamına gelir.

Güncelleme 2

Gereksiz tartışma veya tartışmayı önlemek için, biraz daha detay ekliyorum.

@Asik, GC sivri hakkında ilginç bir fikir verdi. Bu, her yerde değer türü yaklaşımını GC olaylarını reddetmenin bir yolu olarak görebiliriz. Bu oldukça çekici ve hatta bazı sistemlerde uygulanabilir (örneğin tamamen işlevsel bir yaklaşım). Bunun teoride güzel olduğu konusunda hemfikirim. Fakat pratikte bunun birkaç sorunu var. En büyük sorun, bu hilenin kısmi uygulanması, gerçek ani olmayan özellikler sağlamıyor.

Çünkü gecikme sorunu her zaman hep ya hiç sorunudur. 10 saniye boyunca bir kare çiviye sahipseniz (= 600 kare), o zaman tüm sistem açıkça başarısız olur. Bu ne kadar iyi ya da daha kötü değil. Sadece başarılı ya da başarısız. (veya% 0.0001'den az) Öyleyse GC spike'ın kaynağı nerede? GC yükünün kötü dağılımı. Ve bunun nedeni, GC'nin temelde belirsiz olmasıdır. Herhangi bir çöp yaparsanız, GC'yi aktive eder ve sonunda başak olur. Elbette, GC yükünün her zaman ideal olacağı ideal dünyada, bu olmayacak, ama hayali ideal dünyadan ziyade gerçek dünyada yaşıyorum.

O zaman sivri uçlardan kaçınmak istiyorsanız bütün ref-tiplerini tüm sistemden çıkarmalısınız . Ancak .NET çekirdek sistemi ve kütüphanesi gibi taşınamaz kısım nedeniyle zor, çılgınca ve hatta imkansız. Sadece GC olmayan sistemi kullanmak çok kolaydır .

GC'den farklı olarak, RC temelde belirleyicidir ve bu çılgınca optimizasyonu (sadece salt değer tipi) kullanmak zorunda kalmazsınız. Yapmanız gereken, sivri uçlara neden olan parçanın izini sürmek ve optimize etmek. RC sistemlerinde spike yerel algoritma sorunudur, ancak GC sistemlerinde spike her zaman global sistem sorunudur.

Sanırım cevabım konu dışı kaldı ve çoğunlukla mevcut tartışmaların tekrarı. Gerçekten bazı üstünlük / aşağılık / alternatif veya GC / RC maddeleriyle ilgili herhangi bir şey talep etmek istiyorsanız, bu sitede ve StackOverflow'ta birçok tartışma var ve orada savaşmaya devam edebilirsiniz.


4
Çöp toplama, özellikle kuşak, referans sayımından genellikle çok daha hızlıdır .
Jan Hudec

9
@JanHudec Önemli ölçüde daha hızlı gerçek zamanlı grafik alanında sadece anlamsız. Bu yüzden GC'de çok büyük bir sıçrama yapılması gerektiğini söylüyorum. Generation GC, hem teorik hem de pratik olarak sivri uçlu olmaya bile yakın değildir.
Eonil

5
Daha hızlı ve başak ücretsiz tamamen dikey kategorilerdir. Nesil çöp toplayıcıları daha hızlı . Onlar başak serbest değildir .
Jan Hudec

4
Konuştuğun şey verimlilik . Daha hızlı olan her zaman belirsiz bir terimdir ve bağlamda bir şey ifade edebilir. Terimlerin anlamı hakkında tartışmak istiyorsanız, özellikle şu anki bağlam - gerçek zamanlı grafikler göz önüne alındığında daha hızlı değil, daha kesin bir terim kullanmalısınız .
Eonil

11
@JanHudec: Mobil cihazlarda veya kısıtlı kaynaklara sahip herhangi bir cihazda, GC önemli ölçüde daha hızlı değildir ve aslında sorunun büyük bir kısmıdır.
Mason Wheeler

72

Python'dan 3.9 kat daha hızlı olan ve çoğu ölçütleri önemli oranda azaltan dil (tamam, Perl, Ruby ve PHP ile aynıdır; ancak statik olarak yazılmış herhangi bir şeyi kaybeder), bunun hakkında olması gereken bir şey değildir.

Kriterler oyunu daha hızlı piton programlardan daha çoğu durumda büyüklük sırasına daha fazladır C ++ programları gösterir. Statik olarak yazılmayan Java, C # (Mono'da), OCaml, Haskell ve hatta Clojure ile karşılaştırıldığında çok daha iyi değil.

Öyleyse asıl soru, Objective-C'nin pythondan sadece 2.8 kat daha hızlı olmasıdır. Görünüşe göre, ObjC'nin yavaş ve tamamen dinamik gönderilmesinin çok fazla acı verdiği bir yer seçmişlerdi. Statik olarak yazılmış herhangi bir dil daha iyisini yapabilmelidir. Karmaşık nesne sıralamasında nesneleri karşılaştırmak için birçok yöntem çağrısı vardır ve gerçek karşılaştırma muhtemelen çok da karmaşık değildi. Bu yüzden eğer Swift, tip bilgisinden en azından bir miktar faydalanırsa, yöntem çağrıları üzerinde kolayca daha iyi yapabilir ve ObjC'nin daha iyi olabileceği başka yeterli işlem yoktur.

Tabii ki, benchmarklar oyununun açıkça gösterdiği gibi, farklı görevlerdeki göreceli performans çılgınca değişebiliyor, bu yüzden bir benchmark gerçekten destekleyici değil. Daha büyük bir avantaja sahip olduğu bir ölçüt olsaydı, bize bunun yerine bunu gösterirdi, yani diğer görevlerde muhtemelen daha iyi ya da çok değil.


13
Bu cevabın amacını tam olarak anlamadım. "Kriterler kusurludur" diyerek "daha hızlı nasıl yapılır" cevabını mı veriyorsunuz? Yaptığın nokta bu mu? Bunun ne istendiğini nasıl cevapladığını anlamadım.
Bryan Oakley

15
@BryanOakley: Kriterlerin hatalı olduğunu düşünmüyorum, ancak Swift'in daha hızlı olduğu bir kriteri seçmeleri olasılığı kesinlikle göz önünde bulundurulmalı.
Jan Hudec

23
"Swift nasıl daha hızlı?" "Aslında değil" olabilir, @BryanOakley; Jan'in cevabından aldığım özü bu. Sonuçta "Yalanlar, lanet olası yalanlar ve istatistikler".
Josh Caswell

4
Bir süre önce biz Codename One iOS üzerinde çalışan benchmarked ve bizim Java uygulaması çok daha hızlı oldu Objective-C codenameone.com/blog/... Oca doğrudur, dinamik sevk onlara bile biraz geliştirilmiş eğer sonra bazı kriterler olacak, gerçekten yavaş Büyük bir gelişme göster. ARC'yi bir oranla bile iyileştirirlerse (daha iyi kod analizi sayesinde), saçma bir karmaşıklıktan kurtulabilirler. Dil ne kadar kısıtlıysa, derleyici o kadar fazla optimize etmek için yapabilir (Java'ya bakınız) ve Swift kısıtlamalar ekler.
Shai Almog

7
Jan'in cevabı Q1 ve muhtemelen Q2 için mükemmel bir cevap. Bir pazarlama etkinliğindeki kriterleri ana başlık olarak gördüğümde şöyle düşündüm: "Vay, seçilen en iyi durumda sadece 1,3x. Ortalama sonucu ne yapacağız? 0.3x?"
Amin Negm-Awad

5

Objective-C her yöntem çağrısını dinamik olarak gönderir.

Hipotez: Benchmark, Swift derleyicisinin comparemetot sortdöngüsünden çıkmasına izin vermek için statik yazmayı kullanır . Bu, karmaşık bir alt sınıfa değil, dizideki karmaşık nesnelere izin veren dar bir tür kısıtlaması gerektirir.

(Objective-C'de, gerçekten istiyorsanız, yöntem işaretleyicisini aramak için dil çalışma zamanı desteğini arayarak gerçekten arama yöntemini kaldırabilirsiniz. Dizideki tüm örneklerin aynı sınıftan olduğundan emin olmalısınız. .)

Hipotez: Swift, referans sayma çağrılarını döngü dışına optimize eder.

Hipotez: Swift kriter bir Objective-C nesnesinin yerine Karmaşık bir yapı kullanır, bu nedenle sıralama karşılaştırmalarının dinamik yöntem gönderimlerine (alt sınıflama yapılamadığından) veya referans sayma çalışmalarına (değer türü olduğundan) ihtiyaç duymaz.

(Objective-C'de, Objective-C nesnelerini içermediği sürece performans için C / C ++ 'a geri dönebilirsiniz, örneğin bir C yapı dizisi sıralayabilirsiniz.)


3

Açıkçası, kullandıkları testlere kaynağı serbest bırakmazlarsa, Apple'ın konuyla ilgili söylediği hiçbir şeye güvenmem. Unutmayın, 6 ay önce Intel’in Intel tavşanını bir ticari ortamda emdiğini ve yaktığını söylerken, güç kaygılarına dayanarak PPC’den Intel’e geçen şirketin bu olduğunu unutmayın. Swift’in ObjC’den daha fazla kategoride sıralamadan daha hızlı olduğuna dair kesin olarak reddedilemez bir kanıt görmek istiyorum.

Ek olarak, WWDC’de yayımlanan istatistikleri sorgulamak zorundasınız çünkü bunların her yerinde pazarlama kokusu var.

Bunların tümü, hızlı ve ObjC arasında kendim arasında herhangi bir test yapmadığımı söylüyor, ancak bildiğim kadarıyla, kendi LLVM IR uzantılarına sahip ve derleme zamanında ObjC'den daha fazla optimizasyon yapılması mümkün.

Tam Açıklama: https://ind.ie/phoenix/ adresinde bulunan açık kaynaklı bir Swift derleyicisi yazıyorum.

Herhangi biri Swift'in yalnızca Apple donanımında bulunmadığından emin olmak isterse, bana bildirin ve sizi dahil etmekten memnuniyet duyarım.


2
Bu daha fazla bir telaşlı yorum gibi, okur nasıl cevap
gnat

2
Şimdi daha iyi? :)
greg.casamento

0

Swift eğitiminde kendimi zorladım ve bana öyle geliyor ki Swift'in Dünya'dan daha az olması (beni Visual Basic hakkında düşündürüyor) Objective-C'den daha az “nesne ifreleme” ile. C veya C ++ 'ı hesaba katmış olsalardı, ikincisinin kazanacağını sanıyorum, çünkü sadece daha derleme zamanı.

Bu durumda, Objective-C'nin nesne yönelimli saflığının (ve ek yükünün) kurbanı olduğunu düşünüyorum.


13
"Karmaşık nesne sıralama" bir kıyaslama yapmak, C gibi bir dilde yerel nesneler uygulamayan bir dilde zor olabilir. Bu konuşmanın izleyicisinin% 100 Objektif C programcısı olması muhtemel olduğu göz önüne alındığında, C ++ gibi bir dili karşılaştırmak da pek bir anlam ifade etmiyor. Hızlı olan, "hey, bu şimdiye kadarki en harika dil!" Değil. ama "hey, bu OSX / iOS geliştirme için şu anda kullandığınız dilden daha hızlı".
Bryan Oakley

10
C, qsortkarmaşık nesne sıralamasını mümkün kılacak mükemmel bir para cezasına sahiptir; sadece eldeki nesneleri anlayan bir geri arama kullanır. C ++ 'nın eksik olduğundan şüpheleniyorum çünkü std::sortSwift'i utandırıyor. (Bir şablon olduğu için, bir C ++ derleyicisi unrolling döngüsüne kadar onu büyük ölçüde optimize edebilir.)
MSalters

@ MSalters: Sana tamamen katılıyorum. Hem C hem de C ++ Swift'i geçme yetenekleri var. Yapılan testi almak mümkün olur mu. Ben Swift, Objective-C, C ++ ve C ile aynı kriter yürütmek daha istekli değilim
Siyah Boyalı

@BryanOakley ayrıca, "Bu dil daha az köşeli ayraç gerektirir!"
Nick Bedford

1
Bu cevap hiç su tutmuyor ve çok yanıltıcı. OO gerçekten yavaş değil, aslında bulacağınız en hızlı sistemler C ++, Java ve C # olacak ve programlamanın tarzı (ağır derecede OO ya da değil) programlamanın sonuç hızları ile gerçekten çok az ilgisi olacak. hatalı kod
Bill K,
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.