Bir işlevin Big O yürütme süresini değiştirdiğinizde buna ne denir [kapalı]


19

Diyelim ki bir veritabanını O(n^2)zamanında ayıran bir fonksiyonum var . Yeniden işlemeye devam etmek istiyorum, böylece O(n log(n))zamanında çalışır ve bunu yaparken, dönüş değerlerini ve girişlerini eşdeğer tutarken, işlemin temel yolunu değiştireceğim.

Bu yeniden düzenleme faaliyetine ne denir?

Bir algoritmayı yürüttüğü büyük O hızını değiştirmeden daha hızlı çalıştırabildiğiniz için, "hızlandırma-ifying" pek doğru görünmüyor.

"Basitleştirmek" de doğru görünmüyor.

Bu etkinliğe ne diyorum?

Güncelleme

Bulabildiğim en iyi cevap asimpotik zaman karmaşıklığını azaltmak.


Değişikliklerden sonra çoğu kullanım durumunda algoritmaların daha hızlı olması bekleniyor mu? Bunu not etmek gerekirse, bazen daha tutarlı bir performans davranışı elde etmek için beklenen ortalama performans vuruşunda bile daha iyi bir ölçeklendirme karmaşıklık sınıfına geçmek güzeldir.
Nat

22
Bu yeniden düzenleme değil
theonlygusti

6
Açıkçası, O(log(n))zaman içinde çalışan işlev de zaman içinde çalışır O(n^2). Anlamı O(n^2)"ikinci dereceden daha hızlı büyümez." Muhtemelen Theta (log (n)) demek istediniz, yani "kadar hızlı büyür log(n)". en.wikipedia.org/wiki/…
Džuris

4
<pedantic> bir işlevin büyük o yürütme süresini değiştirmediniz. işlev, bir etki alanı ile bir etki alanı arasındaki ilişkidir ve insani uygulama girişimlerinizden bağımsız olarak bulunur. bunun yerine </pedantic> <human> iyi iş </human> işlevini uygulayan daha iyi performans gösteren bir algoritma buldunuz
emory

5
@theonlygusti: Değişir. İşlev daha önce karmaşıklıklar konusunda bir garanti / garanti verdiyse, yeniden düzenleme yapmaz. Hiçbir şey garanti etmediyse, yeniden düzenliyor. Eğer garanti vermemekle ilgili açık olsa bile, bu özellikle bir yeniden düzenleme.
phresnel

Yanıtlar:


44

Genellikle "performans optimizasyonu" denir , ancak bu terim tipik olarak görünür davranışını değiştirmeyen kod değişikliklerine atıfta bulunduğundan, "yeniden düzenleme" olarak adlandırmazdım . Ve Big-O'daki bir değişiklik kesinlikle görünür bir değişiklik diyeceğim bir şey.

böylece operasyonun temel yolunu değiştireceğim

Bu durumda, optimizasyonunuz bu işlevin yeniden yazılmasıdır . Her optimizasyon, "Big-O" değiştirse bile, mutlaka bir yeniden yazma işlemi değildir, bazen böyle bir iyileştirmeyi sağlamak için sadece küçük değişiklikler gerekir, ancak o zaman bile, bunun için "yeniden düzenleme" terimini kullanmakta isteksizim çünkü değişimin doğası hakkında yanlış bir izlenim bırakma eğilimindedir.

DÜZENLEME: Fowler'ın yeniden düzenleme listesini kontrol ettim ve bu ~ 100 adlı yeniden düzenleme arasında en sonuncusu "Yedek Algoritma" olarak adlandırılıyor . Bu yüzden bunu kanonik referans olarak alırsak, tarif edilen formun optimizasyonuna özel bir yeniden düzenleme adı verilebilecek küçük bir gri alan vardır (ancak IMHO tipik bir alan değildir). Ayrıca unutmayın, Fowler'in tüm yeniden düzenlemelerle hedefi, mevcut kodun yeniden yazılmadan sürdürülebilmesi ve geliştirilebilirliğine odaklanarak ve her zaman performans optimizasyonuna açık olmayan tasarımı geliştirmekti.


10
Gerçekten mi? Gereksinimler değişmedikçe yeniden düzenlemenin doğru olduğunu düşünürdüm. Yani .. Eğer fonksiyon BubbleSort olarak adlandırılırsa, evet ise sadece Sort
Ewan

3
@Ewan Evet, yasal olarak bir yeniden düzenleme bir performans optimizasyonu olabilir, ancak birincisi çok geneldir ve değişikliklerin etkisini uygun şekilde yakalamaz.
Tekilleştirici

1
Refactoring'i (Fowler?) İcat eden ve icat eden adam tarafından erken bir sunumdaydım ve tüm fikir, girdi ve çıktı üzerinde hiçbir etkisi olmayan kodda otomatik programlamaya ve kanıtlanabilir doğrulanabilir iyileştirmelere bağlandı.
Sentinel

1
@Steve. Kabul. Ben sadece Big O iyileştirmelerinin algoritmik iyileştirmeyi temsil ettiği, bu algoritmaların nasıl temsil edildiği veya korunduğuna ilişkin iyileştirmeler olmadığı konusunda fikir birliğine katıyordum. Başka bir deyişle, etkinlik bir yeniden
Sentinel

1
@Steve: evet, biliyordum, cevabıma bir not eklemeyi düşündüm. Düzenlemem, küçük, gri bir alan olduğunu açıkça belirtmek için bir nottu.
Doc Brown

13

Ben sık kullanılmakta, standart bir terim olduğunu sanmıyorum optimize olsa iyileştirilmesi veya hızlandırmak ayrıca kod değişiklikleri ve olmayan donanım değişiklikleri bahsediyoruz o açıklama yaparak doğru olacaktır.


7

Diğerlerinin söylediği gibi, "optimizasyon" bir algoritmanın performansını artırmak için kullanılan genel terimdir. Ancak, optimizasyon genellikle sabit faktörlerin iyileştirilmesi anlamına gelir. Eğer asimptotik (zaman) karmaşıklığını azalttığımı kısaca ama açıkça belirtmek istersem, "asimptotik performansı iyileştirdiğimi" söyleyebilirim. Bazen insanlar bunu "ölçeğin iyileştirilmesi" olarak tanımlayacaktır, ancak bu günümüzde özellikle belirsizdir.

Uyarı : Asimptotik zaman karmaşıklığının azaltılması, pratik bir bağlamda optimizasyon ile aynı olmak zorunda değildir . Çoğu zaman asimtotik olarak optimal olmayan algoritmalar kullanılır, çünkü girdi aralığında program aslında daha az optimal algoritmalara daha az maruz kalır, daha iyi performans gösterir.


5

Bağlama bağlı olacaktır.

"İkinci dereceden çalışma zamanı performans hatasını düzeltmek" genellikle gördüğüm şeydir. Ancak, düzeltmeyi (kod değişikliğini) hak edip etmediği bağlama bağlıdır.

Veritabanlarının zaman karmaşıklığını artırmak için birçok araç sağladığını unutmayın. Örneğin, bir veritabanından en iyi N sonucunu almak için şunu söylemeniz yeterlidir. Verimsiz çamuru yerleşik optimize edilmiş aramaya dönüştürürken açıklama gereksiz görünüyor.

Bir kod incelemesini (tartışmayı) hak etmek için ikinci dereceden çalışma zamanına sahip bir algoritmayı dikkate almamın nedeni, yavaş olduğu için (yavaş göreceli; kareli üstel ile karşılaştırıldığında hızlıdır) değil, insan sezgisi (müşterileriniz veya diğer programcılar) günlük yaşamdan beklentilerin karıştırılması nedeniyle doğrusal çalışma süresinden çok farklı bir yazılım işlevselliğinden rahatsız olurlar.

Yazılım performansı ile ilgili birçok müşteri şikayeti bu iki kategoriye girmektedir:

  • Tüm sistem (yazılım ve donanım) tahmini kullanıma göre belirlenmiştir. Geçen hafta, her şey yolunda gidiyor, belirli bir işlevsellik 5 saniyeden az sürdü. Bu hafta, bir güncelleme yükledikten sonra aynı işlevsellik 1 dakikadan fazla sürüyor.

    • Bu, daha önce karşılaştırılmış bir performansla yapılan bir karşılaştırmadır. Müşteri, gelecekteki performansı bir insan zaman ölçeğinin mutlak ölçüsüne sahiptir (saniyelerden dakikaya).
  • Sisteme 100 iş gönderdim. Tek bir iş için geçen süreye kıyasla neden işlenmesi 400 kat sürüyor?

    • Müşteri işlem süresinin doğrusal olmasını beklemektedir. Aslında, müşteri doğrusaldan daha yavaş görevler olduğunu anlayamaz veya kabul edemez.

Bu nedenle, müşteri her ikisi de doğruysa yürütme süresini bir hata olarak değerlendirir:

  • Doğrusaldan daha yavaş
  • Farkedilir (yani, tipik görev boyutları göz önüne alındığında insan zaman aralığına (saniye veya dakikadan daha uzun) düşer)

İkinci dereceden bir çalışma zamanı algoritmasının sorun oluşturmadığını (yani bir kod değişikliğini hak etmediğini) açıklayan meşru argümanlar:

  • Bu ikinci dereceden çalışma zamanı işlevi tarafından işlenen görevin boyutu biraz sınırlıdır
  • Tipik boyut aralığı göz önüne alındığında, gerçek (mutlak) yürütme süresi hala reddedilecek kadar küçüktür
  • Bir kullanıcı gerçekten farkedilebilecek kadar büyük bir görev göndermeye çalışırsa, kullanıcı uzun çalışma süresi hakkında bir uyarı mesajı alır.
  • Sistem kullanıcılarının hepsi uzman, bu yüzden ne yaptıklarını biliyorlar. Örneğin, bir API kullanıcılarının API belgelerindeki ince baskıyı okuması gerekir.

Tipik uygulama geliştirme için yararlı olan birçok algoritma aslında lineerden daha yavaştır (sıralamada olduğu gibi çoğunlukla O (N log N)), bu nedenle büyük ölçekli yazılım aslında, yalnızca ilgili parçayı sıralayarak veya benzer etkiyi sağlayan histogram (istatistiksel) filtreleme tekniklerini kullanın.

Bu, yazılım müşterileri için geçerlidir, ancak bir yazılım kitaplığı veya API işlevinin kullanıcılarının da "müşteriler" olduğunu düşünüyorsanız, yanıt yine de geçerli olacaktır.


2

Orijinal algoritma doğru bir şekilde uygulandıysa (veya ilgisiz olan herhangi bir hata) , "algoritmayı değiştirme" veya "algoritma değiştirme" , çünkü bu değişiklikler tam olarak yaptığınız anlamına gelir; daha önce kullanılan algoritma için farklı zaman karmaşıklığına sahip bir algoritmanın kullanılması.

Önceki zaman karmaşıklığı uygulanmasındaki bir hata nedeniyle olması durumunda (örneğin yanlışlıkla bir dizi üzerinde bir iç döngü başlangıç noktasını sıfırlamak ne olmalıydı O (n) O haline geldiğini (n bunu söylemek 2 sonra)) "sabitleme ikinci dereceden maliyet hatası " veya benzeri.

Bir çakışma var, böyle bir durumda, işin O (n) zamanında yapılabileceğini ve O (n 2 ) süresinin bir hata olduğunu biliyorsanız, kod üzerindeki etki aynıdır veya önce kasıtlı olarak O (n 2 ) zamanında uyguladınız ve daha sonra başlangıç ​​noktasını sıfırlamadan yine de doğru çalışacağını fark ettiniz ve böylece O (n 2 ) için bir O (n) algoritmasının yerini aldınız .


1

Bir sipariş / büyüklük siparişleri ile hız optimizasyonu. Bu matematiksel olarak yanlış bir dil olmasına rağmen, Düzenin değiştirilme fikrini en iyi şekilde aktarır.

Ölçeklenebilirlik geliştirildi. duydum.

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.