Program optimizasyonu - Program optimization

İçinde bilgisayar Bilimi, program optimizasyonu, kod optimizasyonu, veya yazılım optimizasyonu bir yazılım sisteminin bazı yönlerinin daha fazla çalışması için değiştirilmesi sürecidir verimli bir şekilde veya daha az kaynak kullanın.[1] Genel olarak bir bilgisayar programı daha hızlı çalışması için veya daha az maliyetle çalışabilmesi için optimize edilebilir Bellek saklama alanı veya diğer kaynaklar veya daha az güç çeker.

Genel

"Optimizasyon" kelimesi "optimal" ile aynı kökü paylaşsa da, optimizasyon sürecinin gerçekten optimal bir sistem üretmesi nadirdir. Bir sistem genellikle mutlak terimlerle değil, yalnızca belirli bir kalite ölçütüyle ilgili olarak optimal hale getirilebilir ve bu, diğer olası ölçütlerle zıt olabilir. Sonuç olarak, optimize edilmiş sistem tipik olarak yalnızca bir uygulamada veya tek bir hedef kitle için optimum olacaktır. Bir programın bazı görevleri yerine getirmek için harcadığı süreyi, daha fazla bellek tüketmesi pahasına azaltabilir. Bellek alanının önemli olduğu bir uygulamada, kasıtlı olarak daha yavaş bir algoritma daha az bellek kullanmak için. Çoğu zaman, her durumda iyi çalışan "herkese uyan tek bir boyut" tasarımı yoktur. mühendisler Yapmak takas en büyük ilgi alanlarını optimize etmek için. Ek olarak, bir yazılım parçasını tamamen optimum hale getirmek için gereken çaba - daha fazla iyileştirme yapamaz - neredeyse her zaman tahakkuk edecek faydalar için makul olandan daha fazladır; bu nedenle optimizasyon süreci, tamamen optimal bir çözüme ulaşılmadan durdurulabilir. Neyse ki, çoğu zaman en büyük iyileştirmeler sürecin başlarında ortaya çıkar.

Belirli bir kalite ölçütü için bile (yürütme hızı gibi), çoğu optimizasyon yöntemi yalnızca sonucu iyileştirir; optimum çıktı üretme iddiası yoktur. Süperoptimizasyon gerçekten optimal çıktı bulma sürecidir.

Optimizasyon seviyeleri

Optimizasyon birkaç seviyede gerçekleşebilir. Tipik olarak daha yüksek seviyeler daha büyük etkiye sahiptir ve daha sonra bir projede değiştirilmesi daha zordur, bu da önemli değişiklikler veya değiştirilmesi gerekiyorsa tamamen yeniden yazmayı gerektirir. Bu nedenle, optimizasyon tipik olarak, ilk kazançların daha büyük olması ve daha az işle elde edilmesi ve daha sonraki kazanımların daha küçük olması ve daha fazla çalışma gerektirmesi ile yukarıdan aşağıya iyileştirme yoluyla ilerleyebilir. Bununla birlikte, bazı durumlarda genel performans, bir programın çok düşük seviyeli bölümlerinin performansına bağlıdır ve geç bir aşamadaki küçük değişiklikler veya düşük seviyeli ayrıntıların erken değerlendirilmesi, çok büyük bir etkiye sahip olabilir. Tipik olarak, bir proje boyunca verimliliğe bir miktar önem verilir - bu önemli ölçüde değişiklik gösterse de - ancak büyük optimizasyon genellikle, hiç değilse geç yapılması gereken bir iyileştirme olarak kabul edilir. Daha uzun süren projelerde tipik olarak optimizasyon döngüleri vardır, burada bir alanı iyileştirmek diğerindeki sınırlamaları ortaya çıkarır ve bunlar genellikle performans kabul edilebilir olduğunda veya kazançlar çok küçük veya maliyetli olduğunda azalır.

Performans, bir programın spesifikasyonunun bir parçası olduğu için - kullanılamayacak kadar yavaş olan bir program amaca uygun değildir: 60 Hz (saniyede kare) olan bir video oyunu kabul edilebilir, ancak saniyede 6 kare kabul edilemez derecede dalgalıdır - performans, sistemin yeterli performansı sağlayabilmesini sağlamak için en baştan bir değerlendirmedir ve nihai sistemin (optimizasyonla) kabul edilebilir performansa ulaşacağına dair güven için erken prototiplerin kabaca kabul edilebilir performansa sahip olması gerekir. Optimizasyonun her zaman daha sonra yapılabileceği inancında bu bazen göz ardı edilir, bu da çok yavaş prototip sistemlere neden olur - genellikle büyüklük sırası veya daha fazlası - ve mimari olarak performans hedeflerine ulaşamadıkları için sonuçta başarısız olan sistemler, örneğin Intel 432 (1981); veya kabul edilebilir performansa ulaşmak için yıllarca çalışma gerektiren, Java (1995) gibi, yalnızca kabul edilebilir performans elde eden Sıcak nokta (1999). Prototip ve üretim sistemi arasındaki performansın ne derece değiştiği ve optimizasyona ne kadar uygun olduğu, önemli bir belirsizlik ve risk kaynağı olabilir.

Tasarım seviyesi

En üst düzeyde, tasarım, mevcut kaynaklardan, verilen hedeflerden, kısıtlamalardan ve beklenen kullanım / yükten en iyi şekilde yararlanmak için optimize edilebilir. Bir sistemin mimari tasarımı, performansını büyük ölçüde etkiler. Örneğin, ağ gecikmesine bağlı bir sistem (ağ gecikmesinin genel performans üzerindeki ana kısıtlamadır), ideal olarak tek bir istek yaparak (veya bir istekte bulunmayarak) ağ gezilerini en aza indirecek şekilde optimize edilecektir. push protokolü ) birden çok gidiş dönüş yerine. Tasarım seçimi hedeflere bağlıdır: tasarım yaparken derleyici hızlı derleme temel öncelikse, tek geçişli derleyici a'dan daha hızlı çok geçişli derleyici (aynı işi varsayarsak), ancak hedef çıktı kodunun hızı ise, daha yavaş bir çok geçişli derleyici, daha uzun sürmesine rağmen hedefi daha iyi yerine getirir. Platform ve programlama dili seçimi bu seviyede gerçekleşir ve bunların değiştirilmesi sık sık tam bir yeniden yazma gerektirir, ancak modüler bir sistem yalnızca bazı bileşenlerin yeniden yazılmasına izin verebilir - örneğin, bir Python programı C'deki performans açısından kritik bölümleri yeniden yazabilir. sistem, mimari seçimi (müşteri sunucusu, Eşler arası vb.) tasarım düzeyinde oluşur ve özellikle tüm bileşenler senkronize olarak değiştirilemiyorsa (örneğin eski istemciler) değiştirilmesi zor olabilir.

Algoritmalar ve veri yapıları

Genel bir tasarım göz önüne alındığında, iyi bir seçim verimli algoritmalar ve veri yapıları ve bu algoritmaların ve veri yapılarının verimli bir şekilde uygulanması daha sonra gelir. Tasarımdan sonra seçim algoritmalar ve veri yapıları, verimliliği programın diğer tüm yönlerinden daha fazla etkiler. Bir veri yapısı varsayımı ve performans varsayımları program boyunca kullanıldığından, genellikle veri yapılarının değiştirilmesi algoritmalardan daha zordur, ancak bu, aşağıdakilerin kullanılmasıyla en aza indirilebilir. soyut veri türleri fonksiyon tanımlarında ve somut veri yapısı tanımlarını birkaç yerle sınırlı tutmak.

Algoritmalar için bu, öncelikle algoritmaların sabit O (1), logaritmik O (log n), doğrusal O (n) veya bazı durumlarda log-lineer O (n günlük n) girişte (hem uzay hem de zamanda). İkinci dereceden karmaşıklık O (n2) ölçeklenemez ve hatta doğrusal algoritmalar tekrar tekrar çağrıldığında sorunlara neden olur ve mümkünse tipik olarak sabit veya logaritmik ile değiştirilir.

Asimptotik büyüme düzeninin ötesinde, sabit faktörler önemlidir: asimptotik olarak daha yavaş bir algoritma, her ikisi de küçük girdi ile karşı karşıya kaldıklarında, asimptotik olarak daha hızlı bir algoritmadan daha hızlı veya daha küçük (çünkü daha basit) olabilir, ki bu gerçekte meydana gelebilir. Genellikle bir hibrit algoritma boyutla birlikte değişen bu ödünleşim nedeniyle en iyi performansı sağlayacaktır.

Performansı iyileştirmek için genel bir teknik, işten kaçınmaktır. İyi bir örnek, bir hızlı yol yaygın durumlar için, gereksiz işlerden kaçınarak performansı artırmak. Örneğin, Latince metin için basit bir metin düzeni algoritması kullanarak, yalnızca aşağıdaki gibi karmaşık komut dosyaları için karmaşık bir düzen algoritmasına geçme Devanagari. Diğer bir önemli teknik, özellikle hafızaya alma gereksiz hesaplamaları önleyen. Önbelleğe almanın önemi nedeniyle, bir sistemde genellikle bellek kullanımından kaynaklanan sorunlara ve eski önbelleklerden kaynaklanan doğruluk sorunlarına neden olabilecek pek çok önbelleğe alma düzeyi vardır.

Kaynak kodu seviyesi

Genel algoritmaların ve bunların soyut bir makinede uygulanmasının ötesinde, somut kaynak kodu seviyesi seçimleri önemli bir fark yaratabilir. Örneğin, eski C derleyicilerinde, süre (1) daha yavaştı için(;;) koşulsuz bir döngü için, çünkü süre (1) 1'i değerlendirdi ve ardından doğru olup olmadığını test eden koşullu bir sıçrama yaptı. için (;;) koşulsuz bir sıçrama yaşadı. Bazı optimizasyonlar (bunun gibi) günümüzde derleyicileri optimize etme. Bu, kaynak dile, hedef makine diline ve derleyiciye bağlıdır ve hem anlamak hem de tahmin etmek zor olabilir ve zamanla değişebilir; bu, derleyicilerin ve makine kodunun anlaşılmasının performansı artırabileceği önemli bir yerdir. Döngüde değişmeyen kod hareketi ve getiri değeri optimizasyonu yardımcı değişkenlere olan ihtiyacı azaltan ve hatta yuvarlak optimizasyonlardan kaçınarak daha hızlı performansla sonuçlanabilen optimizasyon örnekleridir.

İnşa seviyesi

Kaynak ve derleme düzeyi arasında, direktifler ve bayrak inşa etmek sırasıyla kaynak kod ve derleyicideki performans seçeneklerini ayarlamak için kullanılabilir, örneğin önişlemci gereksiz yazılım özelliklerini devre dışı bırakmayı, belirli işlemci modelleri veya donanım yeteneklerini optimize etmeyi veya tahmin etmeyi tanımlar dallanma, Örneğin. Gibi kaynak tabanlı yazılım dağıtım sistemleri BSD 's Portlar ve Gentoo 's Portage bu optimizasyon biçiminden yararlanabilir.

Derleme düzeyi

Bir optimize edici derleyici sağlama eğilimindedir çalıştırılabilir program en azından derleyicinin tahmin edebileceği kadar optimize edilmiştir.

Montaj seviyesi

En düşük seviyede, bir montaj dili, belirli bir donanım platformu için tasarlanmış, programcı tüm repertuarından yararlanırsa en verimli ve kompakt kodu üretebilir. makine talimatları. Birçok işletim sistemleri kullanılan gömülü sistemler bu nedenle geleneksel olarak assembler koduyla yazılmıştır. Programlar (çok küçük programlar dışında), ilgili zaman ve maliyet nedeniyle nadiren baştan sona derlemede yazılır. Çoğu, yüksek seviyeli bir dilden derlenir ve oradan elle optimize edilir. Verimlilik ve boyut daha az önemli olduğunda, büyük parçalar yüksek seviyeli bir dilde yazılabilir.

Daha modern derleyicileri optimize etme ve yakın zamandaki daha karmaşık CPU'lar, derleyicinin ürettiğinden daha verimli kod yazmak daha zordur ve çok az proje bu "nihai" optimizasyon adımına ihtiyaç duyar.

Bugün yazılan kodların çoğu, olabildiğince çok makinede çalışmayı amaçlamaktadır. Sonuç olarak, programcılar ve derleyiciler yeni CPU'lar tarafından sağlanan daha verimli talimatlardan veya eski modellerin tuhaflıklarından her zaman yararlanamazlar. Ek olarak, bu tür talimatlar kullanılmadan belirli bir işlemci için ayarlanmış derleme kodu, farklı bir işlemcide yine de yetersiz olabilir ve kodun farklı bir şekilde ayarlanmasını bekleyebilir.

Tipik olarak bugün, programcılar derleme dilinde yazmak yerine bir sökücü bir derleyicinin çıktısını analiz etmek ve daha verimli bir şekilde derlenebilmesi için yüksek seviyeli kaynak kodunu değiştirmek veya neden verimsiz olduğunu anlamak.

Çalışma süresi

Tam zamanında derleyiciler, derleme ek yükü pahasına çalışma zamanı verilerine dayalı özelleştirilmiş makine kodu üretebilirler. Bu teknik en erken tarihe dayanır Düzenli ifade motorlar ve Java HotSpot ve JavaScript için V8 ile yaygınlaştı. Bazı durumlarda uyarlanabilir optimizasyon gerçekleştirebilir Çalışma süresi Gerçek girdiye veya diğer faktörlere göre parametreleri dinamik olarak ayarlayarak statik derleyicilerin kapasitesini aşan optimizasyon.

Profil yönlendirmeli optimizasyon çalışma süresi profillerine dayalı bir zaman öncesi (AOT) derleme optimizasyon tekniğidir ve uyarlamalı optimizasyonun dinamik tekniğinin statik "ortalama durumu" analoğuna benzer.

Kendi kendini değiştiren kod kodu optimize etmek için çalışma süresi koşullarına yanıt olarak kendini değiştirebilir; bu, assembly dili programlarında daha yaygındı.

Biraz CPU tasarımları çalışma zamanında bazı optimizasyonlar gerçekleştirebilir. Bazı örnekler şunları içerir: Arıza yürütme, Spekülatif uygulama, Talimat ardışık düzenleri, ve Dal belirleyicileri. Derleyiciler, programın bu CPU özelliklerinden yararlanmasına yardımcı olabilir, örneğin talimat planlaması.

Platforma bağlı ve bağımsız optimizasyonlar

Kod optimizasyonu, genel olarak şu şekilde kategorize edilebilir: platform bağımlı ve platformdan bağımsız teknikler. İkincisi, çoğu platformda veya tüm platformlarda etkili olsa da, platforma bağlı teknikler, bir platformun belirli özelliklerini kullanır veya tek platforma veya hatta tek işlemciye bağlı olarak parametrelere dayanır. Bu nedenle, farklı işlemciler için aynı kodun farklı sürümlerini yazmak veya üretmek gerekli olabilir. Örneğin, derleme düzeyinde optimizasyon durumunda, platformdan bağımsız teknikler genel tekniklerdir (örneğin döngü açma, çoğu CPU mimarisini benzer şekilde etkileyen işlev çağrılarında azalma, bellek verimli rutinler, koşullarda azalma vb.). İç for döngüsü ile platformdan bağımsız optimizasyonun harika bir örneği gösterildi; burada iç for döngüsüne sahip bir döngünün birim zamanda, onsuz veya iç while döngüsüne sahip bir döngüden daha fazla hesaplama yaptığı gözlemlendi.[2] Genellikle bunlar toplamı azaltmaya yarar komut yolu uzunluğu programı tamamlamak ve / veya işlem sırasında toplam bellek kullanımını azaltmak için gereklidir. Öte yandan, platforma bağlı teknikler talimat planlamasını içerir, öğretim düzeyinde paralellik, veri seviyesinde paralellik, önbellek optimizasyon teknikleri (yani, çeşitli platformlar arasında farklılık gösteren parametreler) ve optimal talimat planlaması, aynı mimarinin farklı işlemcilerinde bile farklı olabilir.

Güç azaltma

Hesaplamalı görevler, değişen verimlilikle birkaç farklı şekilde gerçekleştirilebilir. Eşdeğer işlevselliğe sahip daha verimli bir sürüm, güç azalması. Örneğin, aşağıdakileri düşünün C 1'den 1'e kadar olan tüm tam sayıların toplamını elde etmek olan N:

int ben, toplam = 0;için (ben = 1; ben <= N; ++ben) {  toplam += ben;}printf("toplam:% d n", toplam);

Bu kod (hayır varsayarsak) olabilir aritmetik taşma ) aşağıdaki gibi matematiksel bir formül kullanılarak yeniden yazılmalıdır:

int toplam = N * (1 + N) / 2;printf("toplam:% d n", toplam);

Optimizasyon derleyicisi tarafından bazen otomatik olarak gerçekleştirilen optimizasyon, bir yöntem seçmektir (algoritma ) aynı işlevselliği korurken hesaplama açısından daha verimli. Görmek algoritmik verimlilik bu tekniklerden bazılarının tartışılması için. Bununla birlikte, performansta önemli bir iyileşme, genellikle gereksiz işlevsellik kaldırılarak elde edilebilir.

Optimizasyon her zaman açık veya sezgisel bir süreç değildir. Yukarıdaki örnekte, "optimize edilmiş" sürüm aslında orijinal sürümden daha yavaş olabilir, eğer N yeterince küçüktü ve belirli donanım, eklemeyi gerçekleştirmede çok daha hızlı oluyor ve döngü çarpma ve bölmeden ziyade işlemler.

Takas

Ancak bazı durumlarda optimizasyon, daha ayrıntılı algoritmalar kullanmaya, "özel durumlardan" ve özel "hilelerden" yararlanmaya ve karmaşık değiş tokuşları gerçekleştirmeye dayanır. "Tamamen optimize edilmiş" bir programın anlaşılması daha zor olabilir ve bu nedenle daha fazlasını içerebilir hatalar optimize edilmemiş sürümlerden daha fazla. Belirgin antipatternleri ortadan kaldırmanın ötesinde, bazı kod seviyesi optimizasyonları sürdürülebilirliği azaltır.

Optimizasyon genellikle performansın yalnızca bir veya iki yönünü iyileştirmeye odaklanacaktır: yürütme süresi, bellek kullanımı, disk alanı, bant genişliği, güç tüketimi veya başka bir kaynak. Bu genellikle bir değiş tokuş gerektirir - burada bir faktör diğerlerinin pahasına optimize edilir. Örneğin, boyutunu artırmak önbellek çalışma süresi performansını iyileştirir, ancak aynı zamanda bellek tüketimini de artırır. Diğer yaygın ödünleşmeler arasında kod netliği ve özlülük bulunur.

Optimizasyonu gerçekleştiren programcının, yazılımı bazı işlemler için daha iyi hale getirmeye karar vermesi gereken durumlar vardır, ancak bu, diğer işlemleri daha az verimli hale getirme pahasına olabilir. Bu ödünleşmeler bazen teknik olmayan nitelikte olabilir - örneğin bir rakibin bir kıyaslama ticari başarıyı artırmak için yenilmesi gereken ancak belki de yazılımın normal kullanımını daha az verimli hale getirme yüküyle birlikte gelen sonuç. Bu tür değişiklikler bazen şaka yollu şu şekilde anılır: kötümsemeler.

Darboğazlar

Optimizasyon, bir darboğaz bir sistemde - performans üzerinde sınırlayıcı faktör olan bir bileşen. Kod açısından, bu genellikle bir sıcak nokta - gerekli kaynağın birincil tüketicisi olan kodun kritik bir parçası - ancak G / Ç gecikmesi veya ağ bant genişliği gibi başka bir faktör olabilir.

Bilgisayar biliminde, kaynak tüketimi genellikle bir tür Güç yasası dağıtım ve Pareto prensibi Kaynakların% 80'inin tipik olarak operasyonların% 20'si tarafından kullanıldığı gözlemlenerek kaynak optimizasyonuna uygulanabilir.[3] Yazılım mühendisliğinde, bir bilgisayar programının yürütme süresinin% 90'ının kodun% 10'unu (bu bağlamda 90/10 yasası olarak bilinir) çalıştırmaya harcanması genellikle daha iyi bir yaklaşımdır.

Daha karmaşık algoritmalar ve veri yapıları birçok öğe ile iyi performans gösterirken, basit algoritmalar küçük miktarlarda veri için daha uygundur - daha karmaşık algoritmanın kurulumu, başlatma süresi ve sabit faktörleri faydadan daha ağır basabilir ve bu nedenle hibrit algoritma veya uyarlanabilir algoritma herhangi bir tek algoritmadan daha hızlı olabilir. Hangi işlevselliğin hangi koşullara uyduğuna ilişkin kararları daraltmak için bir performans profili oluşturucu kullanılabilir.[4]

Bazı durumlarda daha fazlasını eklemek hafıza bir programın daha hızlı çalışmasına yardımcı olabilir. Örneğin, bir filtreleme programı genellikle her satırı okuyacak ve bu satırı hemen filtreleyip çıktısını alacaktır. Bu, yalnızca bir satır için yeterli bellek kullanır, ancak her disk okumasının gecikmesi nedeniyle performans genellikle düşüktür. Sonucu önbelleğe almak da benzer şekilde etkilidir, ancak aynı zamanda daha fazla bellek kullanımı gerektirir.

Ne zaman optimize edilmeli

Optimizasyon azaltabilir okunabilirlik ve yalnızca iyileştirmek için kullanılan kodu ekleyin verim. Bu, programları veya sistemleri karmaşık hale getirerek bunların bakımını ve hata ayıklamasını zorlaştırabilir. Sonuç olarak, optimizasyon veya performans ayarlaması genellikle işlemin sonunda gerçekleştirilir. Geliştirme aşaması.

Donald Knuth optimizasyonla ilgili şu iki açıklamayı yaptı:

"Küçük verimlilikleri unutmalıyız, örneğin zamanın yaklaşık% 97'sinde: erken optimizasyon tüm kötülüklerin köküdür. Yine de fırsatlarımızı o kritik% 3'te kaçırmamalıyız"[5]

(Ayrıca alıntıyı Tony Hoare birkaç yıl sonra,[6] Hoare bu ifadeyi icat etmiş olduğunu reddettiği için bu bir hata olabilir.[7])

"Yerleşik mühendislik disiplinlerinde, kolayca elde edilen% 12'lik bir gelişme asla marjinal olarak görülmez ve aynı bakış açısının yazılım mühendisliğinde de geçerli olması gerektiğine inanıyorum."[5]

"Erken optimizasyon", bir programcının performans değerlendirmelerinin bir kod parçasının tasarımını etkilemesine izin verdiği bir durumu açıklamak için kullanılan bir deyimdir. Bu, olabildiğince temiz olmayan bir tasarıma veya hatalı bir koda neden olabilir, çünkü kod optimizasyon nedeniyle karmaşıklaşır ve programcının dikkati optimizasyon nedeniyle dağılır.

Programın belirli bir bölümünü optimize edip etmemeye karar verirken, Amdahl Yasası her zaman göz önünde bulundurulmalıdır: genel program üzerindeki etki, büyük ölçüde o belirli bölümde gerçekte ne kadar zaman harcandığına bağlıdır; bu, bir kod olmadan koda bakmaktan her zaman net değildir. performans analizi.

Bu nedenle daha iyi bir yaklaşım, önce tasarlamak, tasarımdan kodlamak ve ardından profil /kıyaslama hangi parçaların optimize edilmesi gerektiğini görmek için ortaya çıkan kod. Basit ve zarif bir tasarımın bu aşamada optimize edilmesi genellikle daha kolaydır ve profil oluşturma, erken optimizasyonla çözülemeyen beklenmedik performans sorunlarını ortaya çıkarabilir.

Uygulamada, yazılımı ilk tasarlarken genellikle performans hedeflerini akılda tutmak gerekir, ancak programcı tasarım ve optimizasyon hedeflerini dengeler.

Modern derleyiciler ve işletim sistemleri o kadar etkilidir ki, amaçlanan performans artışları çoğu zaman gerçekleşemez. Örnek olarak, işletim sistemi düzeyinde yeniden önbelleğe alınan uygulama düzeyinde verilerin önbelleğe alınması, yürütmede iyileştirmeler sağlamaz. Yine de, programcının başarısız optimizasyonları üretim kodundan kaldırması nadir bir durumdur. Donanımdaki ilerlemelerin, herhangi bir potansiyel iyileştirmeyi engellemekten çok daha fazla olacağı da doğrudur, ancak belirsiz kod, amacı reddedildikten çok sonra da gelecekte devam edecektir.

Makrolar

Kullanarak kod geliştirme sırasında optimizasyon makrolar farklı dillerde farklı biçimler alır.

Gibi bazı prosedürel dillerde C ve C ++ makrolar belirteç değiştirme kullanılarak uygulanır. Şu günlerde, satır içi işlevler olarak kullanılabilir güvenli yazın birçok durumda alternatif. Her iki durumda da, satır içi işlev gövdesi daha sonra derleyici tarafından daha fazla derleme zamanı optimizasyonuna tabi tutulabilir. sabit katlama, bazı hesaplamaları zamanı derlemeye taşıyabilir.

Çoğunda fonksiyonel programlama dil makroları, ayrıştırma ağaçlarının / soyut sözdizimi ağaçlarının ayrıştırma zamanı ikamesi kullanılarak uygulanır ve bunların kullanımını daha güvenli hale getirir. Çoğu durumda yorumlama kullanıldığından, bu tür hesaplamaların yalnızca ayrıştırma zamanında ve bazen de tek şekilde yapılmasını sağlamanın bir yolu budur.

Lisp bu tarz makro yarattı,[kaynak belirtilmeli ] ve bu tür makrolar genellikle "Lisp benzeri makrolar" olarak adlandırılır. Kullanılarak da benzer bir etki elde edilebilir şablon meta programlama içinde C ++.

Her iki durumda da iş, derleme zamanına taşınır. Arasındaki fark C bir tarafta makrolar ve Lisp benzeri makrolar ve C ++ şablon meta programlama diğer taraftan, son araçların derleme zamanı / ayrıştırma zamanında keyfi hesaplamalar yapmaya izin verirken, C makrolar herhangi bir hesaplama yapmaz ve bunu gerçekleştirmek için optimize edicinin yeteneğine dayanır. Bunlara ek olarak, C makrolar doğrudan desteklemiyor özyineleme veya yineleme öyle değil Turing tamamlandı.

Bununla birlikte, herhangi bir optimizasyonda olduğu gibi, bir proje tamamlanmadan önce bu tür araçların en fazla etkiyi nerede yaratacağını tahmin etmek genellikle zordur.

Otomatik ve manuel optimizasyon

Ayrıca bakınız Kategori: Derleyici optimizasyonları

Optimizasyon, derleyiciler tarafından otomatikleştirilebilir veya programcılar tarafından gerçekleştirilebilir. Kazançlar genellikle yerel optimizasyon için sınırlıdır ve global optimizasyonlar için daha büyüktür. Genellikle en güçlü optimizasyon, daha üstün bir algoritma.

Otomatik optimize ediciler için çok karmaşık olduğu için, bir sistemin tamamını optimize etmek genellikle programcılar tarafından yapılır. Bu durumda, programcılar veya sistem yöneticileri, genel sistemin daha iyi performans göstermesi için kodu açıkça değiştirirler. Daha iyi verimlilik üretebilmesine rağmen, otomatik optimizasyonlardan çok daha pahalıdır. Birçok parametre program performansını etkilediğinden, program optimizasyon alanı büyüktür. Meta sezgisel tarama ve makine öğrenimi, program optimizasyonunun karmaşıklığını ele almak için kullanılır.[8]

Kullanın profil oluşturucu (veya performans analizörü ) programın en çok kaynağı alan bölümlerini bulmak için - darboğaz. Programcılar bazen darboğazın nerede olduğuna dair net bir fikirleri olduğuna inanırlar, ancak sezgiler genellikle yanlıştır.[kaynak belirtilmeli ] Önemsiz bir kod parçasını optimize etmek, genel performansa yardımcı olmak için genellikle çok az şey yapar.

Darboğaz yerelleştirildiğinde, optimizasyon genellikle programda kullanılan algoritmanın yeniden düşünülmesi ile başlar. Çoğu zaman, belirli bir algoritma, genel bir algoritmadan daha iyi performans sağlayarak belirli bir soruna özel olarak uyarlanabilir. Örneğin, büyük bir öğe listesini sıralama görevi genellikle bir hızlı sıralama en verimli genel algoritmalardan biri olan rutin. Ancak, öğelerin bazı özelliklerinden yararlanılabilirse (örneğin, zaten belirli bir sırayla düzenlenmişlerse), farklı bir yöntem veya hatta ısmarlama bir sıralama rutini kullanılabilir.

Programcı, en iyi algoritmanın seçildiğinden makul ölçüde emin olduktan sonra, kod optimizasyonu başlayabilir. Döngüler açılabilir (daha düşük döngü yükü için, ancak bu genellikle aşağı aşırı yüklüyse hız CPU önbelleği ), olabildiğince küçük veri türleri kullanılabilir, kayan nokta yerine tamsayı aritmetiği kullanılabilir, vb. (Görmek algoritmik verimlilik bunlar ve diğer teknikler için makale.)

Performans darboğazları, programda kullanılan algoritmalardan veya veri yapılarından çok dil sınırlamalarından kaynaklanabilir. Bazen, programın kritik bir bölümü farklı bir şekilde yeniden yazılabilir. Programlama dili bu, temeldeki makineye daha doğrudan erişim sağlar. Örneğin, çok yaygın yüksek seviye gibi diller Python modüllerin yazılı olması C daha yüksek hız için. Halihazırda C ile yazılmış programlar, montaj. Yazılan programlar D kullanabilir satır içi montajcı.

Bölümleri yeniden yazmak, genel bir durum nedeniyle bu koşullarda "karşılığını verir"temel kural " olarak bilinir 90/10 hukuku Bu, zamanın% 90'ının kodun% 10'unda ve yalnızca% 10'unun kodun kalan% 90'ında harcandığını belirtir. Bu nedenle, programın sadece küçük bir bölümünü optimize etmek için entelektüel çaba harcamak, genel hız üzerinde çok büyük bir etkiye sahip olabilir - eğer doğru parça (lar) bulunabilirse.

Manuel optimizasyon bazen okunabilirliği baltalayan yan etkiye sahiptir. Bu nedenle, kod optimizasyonları dikkatlice belgelenmeli (tercihen satır içi yorumlar kullanılarak) ve bunların gelecekteki geliştirme üzerindeki etkileri değerlendirilmelidir.

Otomatik bir optimizasyon gerçekleştiren programa optimize edici. Çoğu iyileştirici, derleyicilere yerleştirilmiştir ve derleme sırasında çalışır. İyileştiriciler genellikle üretilen kodu belirli işlemcilere göre uyarlayabilir.

Bugün, otomatik optimizasyonlar neredeyse yalnızca aşağıdakilerle sınırlıdır: derleyici optimizasyonu. Bununla birlikte, derleyici optimizasyonları genellikle sabit bir genel optimizasyonlar kümesiyle sınırlı olduğundan, problem tanımlarını ve dile özgü optimizasyonları kabul edebilen ve bir mühendisin özel optimizasyonları belirlemesine olanak tanıyan, önemli ölçüde optimize edici talep vardır. Optimizasyon açıklamalarını kabul eden araçlar denir program dönüşümü sistemler ve C ++ gibi gerçek yazılım sistemlerine uygulanmaya başlanıyor.

Bazı üst düzey diller (Eyfel, Esterel ) kullanarak programlarını optimize edin ara dil.

Şebeke bilişim veya dağıtılmış hesaplama görevleri yüksek kullanıma sahip bilgisayarlardan boşta kalan bilgisayarlara taşıyarak tüm sistemi optimize etmeyi amaçlamaktadır.

Optimizasyon için harcanan zaman

Bazen optimizasyonu gerçekleştirmek için harcanan zamanın kendisi bir sorun olabilir.

Mevcut kodu optimize etmek genellikle yeni özellikler eklemez ve daha da kötüsü, yeni böcekler önceden çalışan kodda (herhangi bir değişikliğin olabileceği gibi). Manuel olarak optimize edilmiş kod bazen optimize edilmemiş koddan daha az "okunabilirliğe" sahip olabileceğinden, optimizasyon da onun sürdürülebilirliğini etkileyebilir. Optimizasyonun bir bedeli vardır ve yatırımın zahmete değer olduğundan emin olmak önemlidir.

Otomatik bir optimize edici (veya optimize edici derleyici kod optimizasyonunu gerçekleştiren bir program), ya hedef programlarının verimliliğini daha da iyileştirmek ya da kendi çalışmasını hızlandırmak için kendisinin optimize edilmesi gerekebilir. Optimizasyon "açık" olarak gerçekleştirilen bir derleme genellikle daha uzun sürer, ancak bu genellikle yalnızca programlar oldukça büyük olduğunda bir sorundur.

Özellikle, tam zamanında derleyiciler performansı Çalışma süresi Hedef koduyla birlikte çalıştırılan derleme bileşeni, genel yürütme hızını artırmanın anahtarıdır.

Referanslar

  • Jon Bentley: Verimli Programlar Yazmak, ISBN  0-13-970251-2.
  • Donald Knuth: Bilgisayar Programlama Sanatı
  1. ^ Robert Sedgewick, Algoritmalar, 1984, s. 84
  2. ^ İç döngü program yapısı: Program yürütmenin daha hızlı bir yolu
  3. ^ Wescott, Bob (2013). The Every Computer Performance Book, 3. Bölüm: Yararlı yasalar. CreateSpace. ISBN  978-1482657753.
  4. ^ "Odaklanarak Performans Profili Oluşturma". Alındı 15 Ağustos 2017.
  5. ^ a b Knuth Donald (Aralık 1974). "Yapısal Programlama ile İfadelere Git". ACM Hesaplama Anketleri. 6 (4): 268. CiteSeerX  10.1.1.103.6084. doi:10.1145/356635.356640.
  6. ^ Tex Hataları, içinde Yazılım - Uygulama ve Deneyim, Cilt 19, Sayı 7 (Temmuz 1989), s. 607–685, Literate Programming (s. 276) adlı kitabında yeniden basılmıştır.
  7. ^ Tony Hoare, bir 2004 e-postası
  8. ^ Memeti, Suejb; Pllana, Sabri; Binotto, Alécio; Kołodziej, Joanna; Brandic, Ivona (26 Nisan 2018). "Paralel bilgi işlem sistemlerinin yazılım optimizasyonu için meta sezgisel tarama ve makine öğrenimini kullanma: sistematik bir literatür incelemesi". Bilgi işlem. Springer Viyana. 101 (8): 893–936. arXiv:1801.09444. Bibcode:2018arXiv180109444M. doi:10.1007 / s00607-018-0614-9.

Dış bağlantılar