Gördüğünüz en saçma kötümserlik nedir? [kapalı]


145

Erken optimizasyonun tüm kötülüklerin kökü olduğunu hepimiz biliyoruz çünkü okunamayan / sürdürülemez koda yol açıyor. Daha da kötüsü, bir kişi "optimizasyon" u daha hızlı olacağını düşündüğü için uyguladığında , ancak sonuçta daha yavaş, hatalı, sürdürülemez vb. Hale geldiğinde, karamsarlıktır . Bunun gördüğünüz en saçma örnek nedir? ?


21
"Pessimization" harika bir kelime.
mqp

Sadece bilmiyorsan diye, burada en son podcast'te dizinin hakkında konuştular.
mmcdole

Yanıtlar:


81

Eski bir projede, muazzam Z-8000 deneyimine sahip bazı (aksi halde mükemmel) gömülü sistem programcılarını miras aldık.

Yeni ortamımız 32-bit Sparc Solaris idi.

Adamlardan biri girdi ve kodumuzu hızlandırmak için tüm girişleri kısaya çevirdi, çünkü RAM'den 16 bit kapmak 32 bit kapmaktan daha hızlıydı.

32 bitlik bir sistemde 32 bitlik değerlerin yakalanmasının 16 bitlik değerlerin yakalanmasından daha hızlı olduğunu göstermek için bir demo programı yazmam ve 16 bitlik bir değer elde etmek için CPU'nun 32 bit genişliğinde olması gerektiğini açıklamam gerekiyordu. bellek erişimi ve ardından 16 bitlik değer için gerekli olmayan bitleri maskeleyin veya kaydırın.


16
Hey matematiğini nerede öğrendin? 1 önbellek / RAM erişimi olan 2 talimat, 1 önbellek / RAM erişimi olan 1 talimattan açıkça daha hızlıdır!
Razor Storm

2
@RazorStorm Bant genişliği ve önbelleğin daha değerli olduğu sonraki makinelerde, bunun tersi doğru olacaktır. Bit maskesi / kaydırma ucuzdur, ancak mümkün olduğunca önbelleğe sığdırmak ve ayrıca bant genişliğini en aza indirmek istersiniz.
Jed

206

"Zamanından önce optimizasyon tüm kötülüklerin köküdür" ifadesinin çok fazla kullanıldığını düşünüyorum. Birçok proje için, bir projenin geç dönemlerine kadar performansı hesaba katmamak bir bahane haline geldi.

Bu söz genellikle insanların çalışmaktan kaçınması için bir koltuk değneğidir. İnsanların gerçekten "Tanrım, bunu önceden düşünmemiştik ve şimdi bununla başa çıkmak için zamanımız yok" demesi gerektiğinde bu cümlenin kullanıldığını görüyorum.

"Karamsarlık" nedeniyle ortaya çıkan sorunların örneklerinden çok daha "saçma" aptal performans sorunları örnekleri gördüm

  • Program başlatılırken aynı kayıt defteri anahtarını binlerce (veya 10 bin) kez okuma.
  • Aynı DLL'yi yüzlerce veya binlerce kez yükleme
  • Dosyalara giden tam yolları gereksiz yere tutarak mega bayt bellek israfı
  • Veri yapılarını, ihtiyaç duyduklarından çok daha fazla bellek kaplayacak şekilde düzenlememek
  • Dosya adlarını veya yollarını MAX_PATH olarak saklayan tüm dizeleri boyutlandırma
  • Olaylar, geri aramalar veya diğer bildirim mekanizmaları olan şeyler için karşılıksız yoklama

Daha iyi bir ifade olduğunu düşündüğüm şey şudur: "Ölçmeden ve anlamadan optimizasyon hiç optimizasyon değildir - sadece rastgele değişimdir".

İyi Performans çalışması zaman alıcıdır - çoğu zaman daha çok özellik veya bileşenin kendisinin geliştirilmesi.


46
"Prematüre" bu sözün anahtar kelimesidir. Onu "ölçmeden ve anlamadan optimizasyon" olarak yeniden ifade etmeniz, anlamı bir parça değiştirmiyor gibi görünüyor. Knuth'un kastettiği tam olarak buydu.
Bill the Lizard

13
@Foredecker: doğru. Çok fazla insan bağlamı unutuyor, bu da bu alıntıyı mikro optimizasyona tamamen karşı koyuyor . Uygulamadan önce uygun algoritmayı seçmek için bir problemi analiz etmek erken değildir, ancak çoğu zaman bu alıntı en tembel, en verimsiz çözümü haklı çıkarmak için fırlatılır.
Shog9

5
Gerçekten bireysel duruma bağlı, erken optimizasyonun bir sorun haline geldiği, yetersiz optimizasyon planlamasının bir sorun haline geldiği daha fazla durum var
Mark Rogers

12
-1: "Optimizasyon" ile doğru tasarım arasında bir fark vardır. Söyleyemeyenler için, iyi bir temel kural, bir "optimizasyonun" kodu okumayı zorlaştırması, ancak daha hızlı veya daha verimli hale getirmesidir. Daha iyi bir tasarım, kodun daha kolay okunmasını (veya en azından daha kötü) ve daha verimli olmasını sağlar.
TED

5
Çok fazla kullanılırsa, SO ile ilgili soru soran nüfus, büyük ölçüde aykırı değerlere yönelir. : D
dkretz

114

Veritabanları kötümserlik oyun alanlarıdır.

Favoriler şunları içerir:

  • "Çok büyük" olduğu için bir tabloyu katlara (tarih aralığına, alfabetik aralığa vb. Göre) bölün.
  • Kullanımdan kaldırılan kayıtlar için bir arşiv tablosu oluşturun, ancak bunu üretim tablosuyla birleştirmeye devam edin.
  • Tüm veritabanlarını (bölüm / müşteri / ürün / vb.)
  • Bir dizine sütun eklemeye direnin çünkü çok büyük yapar.
  • Ham verilerden yeniden hesaplama çok yavaş olduğu için çok sayıda özet tablosu oluşturun.
  • Yer kazanmak için alt alanlara sahip sütunlar oluşturun.
  • Bir dizi olarak alanlara denormalize edin.

Bu aklımın ucunda.


Endeksleme ihtiyacına direnmek, düşünmek sadece acı verici.
Bill the Lizard

2
Evet, neredeyse tüm tablolarının ilişkili bir arşiv tablosuna sahip olduğu ve çoğu sorgunun UNION'un tablo çiftlerini seçtiği büyük bir ABD petrol şirketi için çalışan birini tanıyorum. Performans beklediğiniz gibi!
Tony Andrews

Hah, sanırım her DBA bir noktada arşiv tablosu rotasıyla birleşmiş olmalı. O zamanlar her zaman çok makul görünüyor .
Cruachan


"Alanların bir dizi olarak normalleştirilmesi" konusunu biraz daha detaylandırır mısınız? Burada ne demek istiyorsun?
Bart van Heukelom

87

Bence mutlak bir kural yok: bazı şeyler önceden optimize edilmiş, bazıları ise değil.

Örneğin uydulardan veri paketleri aldığımız bir şirkette çalıştım. Her paketin maliyeti çok büyüktü, bu nedenle tüm veriler yüksek düzeyde optimize edildi (yani paketlendi). Örneğin, enlem / boylam mutlak değerler (yüzen) olarak değil, "mevcut" bir bölgenin "kuzey-batı" köşesine göre ofsetler olarak gönderildi. Kullanılmadan önce tüm verileri paketinden çıkarmak zorunda kaldık. Ama bence bu bir kötümserlik değil, iletişim maliyetlerini düşürmek için akıllı bir optimizasyon.

Öte yandan, yazılım mimarlarımız, paketlenmemiş verilerin çok okunabilir bir XML belgesine biçimlendirilmesi ve bu şekilde veritabanımızda saklanması gerektiğine karar verdiler (her alanın karşılık gelen bir sütunda depolanması yerine). Fikirleri, "XML geleceğidir", "disk alanı ucuzdur" ve "işlemci ucuzdur", dolayısıyla hiçbir şeyi optimize etmeye gerek yoktu. Sonuç olarak, 16 baytlık paketlerimiz tek bir sütunda saklanan 2kB dokümanlara dönüştürüldü ve basit sorgular için bile megabaytlık XML belgelerini belleğe yüklememiz gerekti! Saniyede 50'den fazla paket aldık, böylece performansın ne kadar korkunç olduğunu tahmin edebilirsiniz (BTW, şirket iflas etti).

Yani yine, mutlak bir kural yok. Evet, bazen optimizasyon çok erken bir hatadır. Ancak bazen "cpu / disk alanı / bellek ucuzdur" sloganı tüm kötülüklerin gerçek köküdür.


37
"Cpu / disk alanı / bellek ucuz" un tüm kötülüklerin gerçek kökü olduğuna katılıyorum. +1
ksuralta

5
XML saçmalığını da duydum. Başka bir tank şirketi.
n8wrl

19
@ksuralta: "Cpu / disk alanı / bellek ucuz" düşünceden kaçınmak için uygun bir bahane. Düşünceden kaçınmak, tüm kötülüklerin hayali köküdür.
Piskvor

Bu XMLleştirme benim işyerimde de oldu ve ardından JSONization yapıldı. Hepsi "zahmetli" ilişkisel veritabanı tasarımlarından kaçınmak için.
Tanz87

75

Aman Tanrım, hepsini gördüm galiba. Çoğu zaman, bu performans sorunlarının nedenini gideremeyecek kadar tembel olan veya hatta gerçekten bir performans sorunu olup olmadığını araştıran birinin performans sorunlarını çözme çabasıdır. Bu vakaların çoğunda, sadece belirli bir teknolojiyi denemek isteyen ve umutsuzca parlak yeni çekicine uyan bir çivi arayan kişinin durumu olup olmadığını merak ediyorum.

İşte yeni bir örnek:

Veri mimarı, oldukça büyük ve karmaşık bir uygulamada bir anahtar tabloyu dikey olarak bölümlere ayırmak için ayrıntılı bir öneriyle geliyor. Değişikliğe uyum sağlamak için ne tür bir geliştirme çabası gerektiğini bilmek istiyor. Sohbet şöyle gelişti:

Ben: Bunu neden düşünüyorsunuz? Çözmeye çalıştığınız problem nedir?

O: Tablo X çok geniş, performans nedenleriyle bölümlere ayırıyoruz.

Ben: Çok geniş olduğunu düşündüren nedir?

O: Danışman, bunun tek bir masada olması için çok fazla sütun olduğunu söyledi.

Ben: Ve bu performansı etkiliyor mu?

Him: Evet, kullanıcılar uygulamanın XYZ modülünde aralıklı yavaşlamalar bildirdiler.

Ben: Sorunun kaynağının tablonun genişliği olduğunu nereden biliyorsunuz?

Him: Bu, XYZ modülünün kullandığı anahtar tablodur ve 200 sütun gibidir. Sorun bu olmalı.

Ben (Açıklama): Ancak özellikle XYZ modülü bu tablodaki sütunların çoğunu kullanır ve kullandığı sütunlar tahmin edilemez çünkü kullanıcı uygulamayı o tablodan görüntülemek istediği verileri gösterecek şekilde yapılandırır. Muhtemelen zamanımızın% 95'inde tüm masaları bir araya getirmekle sonuçlanırdık, bu da performansımızı düşürür .

O: Danışman çok geniş olduğunu ve onu değiştirmemiz gerektiğini söyledi.

Ben: Bu danışman kim? Bir danışman tuttuğumuzu bilmiyordum, geliştirme ekibiyle de hiç konuşmadılar.

O: Şey, henüz onları işe almadık. Bu, sundukları bir teklifin parçası, ancak bu veritabanını yeniden yapılandırmamız gerektiğinde ısrar ettiler.

Ben: Uh huh. Dolayısıyla, veritabanı yeniden tasarım hizmetleri satan danışman, veritabanının yeniden tasarlanmasına ihtiyacımız olduğunu düşünüyor ...

Sohbet böyle devam etti. Daha sonra söz konusu tabloya bir kez daha baktım ve egzotik bölümleme stratejilerine gerek kalmadan bazı basit normalleştirme ile daraltılabileceğini belirledim. Bu, elbette performans sorunlarını araştırdığımda (daha önce bildirilmemişti) ve bunları iki faktöre indirdiğimde tartışmalı bir nokta haline geldi:

  1. Birkaç anahtar sütunda eksik dizinler.
  2. Üretim veritabanını doğrudan MSAccess ile sorgulayarak anahtar tablolarını ("çok geniş" olanlar dahil) periyodik olarak kilitleyen birkaç hileli veri analisti.

Tabii ki mimar hala "çok geniş" meta-problemin üzerinde asılı duran tablonun dikey olarak bölünmesi için bastırıyor. Hatta uygulamaya bakmadan veya herhangi bir performans analizi çalıştırmadan veritabanında büyük tasarım değişikliklerine ihtiyacımız olduğunu belirleyebilen başka bir veritabanı danışmanından bir teklif alarak durumunu güçlendirdi.


Aaag MSAccess için prod. Birkaç dakikada bir tüm erişim bağlantılarını kesmek için bir prosedür yazdık tp sonunda kötü olduğu mesajıyla karşılaştı.
Nat

1
Benzer bir işimiz vardı ama artık kullanılmıyordu. Adil olmak gerekirse, Access sorun değildir, sadece neofitlerin performans dışı sorgular oluşturmasını / çalıştırmasını kolaylaştırır.
JohnFx

Şirketimizde, üretim DB'sine eski ad hoc Erişim bağlantılarına bağımlılığımız var. Birkaç sıradan SQL'çinin bir WHERE cümlesini unutması ve ana tabloları kilitlemesi gibisi yoktur!
HardCode

35
"Leylak
renginin

Daha kötü olabilirdi. Excel Sorgu Düzenleyicisi, kullanırken tüm veritabanını kilitler. Bunu bilmediğimde, başka bir şeyde çalışırken günün daha iyi bir bölümü için bir örneğini açık bıraktım. En kötü yanı, MS SQL Server'ın kilidi yapan doğru kullanıcı adını / makineyi rapor etmemesidir. Saatler sonra, sorguladığım ve önce her şeyi kontrol ettiğim görünümün bir parçası olan tabloların kilitlenmesi nedeniyle kilitlenmenin nedeni olduğumu fark ettim.
Esteban Küber

58

CHX-LT'yi tamamen kuluçkaya yatırmak için alphadrive-7 kullanan insanlar gördüm. Bu alışılmadık bir uygulamadır. Daha yaygın uygulama, tamponlamanın azaltılması (daha yüksek net aşırı yük direncine bağlı olarak) için ZT transformatörünü başlatmak ve java tarzı baytgrafikasyonlar oluşturmaktır.

Tamamen karamsar!


10
belki de akı kapasitörünü bozmaya çalışıyorlardı
Mikeage

6
Öyleyse, temelde dahil olan tek yeni ilke, gücün iletkenlerin ve akıların nispi hareketiyle üretilmesi yerine, manyeto relüktans ve kapasitif duraktansın modal etkileşimi ile üretilmesidir.
Matt Rogish

17
+1 çünkü monitörümün zaten temizlenmesi gerekiyordu ;-)
RBerteig

1
Lanet olsun!! Peki ya ecletromagentic-cross-genetical etkisi? Ben de dikkate alınması gerektiğini düşünüyorum. Veya konu bir zombiye dönüşebilir.
Suraj Chandran

1
Üç kelime: "Krom Susturucu Rulmanları."
Allbite

53

Dünyayı sarsan bir şey değil, kabul ediyorum, ama Java'da bir döngü dışında StringBuffer kullanan insanları yakaladım. Dönmek gibi basit bir şeydi

String msg = "Count = " + count + " of " + total + ".";

içine

StringBuffer sb = new StringBuffer("Count = ");
sb.append(count);
sb.append(" of ");
sb.append(total);
sb.append(".");
String msg = sb.toString();

Tekniği bir döngüde kullanmak oldukça yaygın bir uygulamadır çünkü ölçülebilir derecede daha hızlıydı. Mesele şu ki, StringBuffer senkronize edildi, bu yüzden sadece birkaç String'i birleştiriyorsanız aslında fazladan ek yük var. (Farkın bu ölçekte kesinlikle önemsiz olduğundan bahsetmiyorum bile.) Bu uygulama hakkında diğer iki nokta:

  1. StringBuilder eşitlenmemiş olduğundan, kodunuzun birden çok iş parçacığından çağrılamadığı durumlarda StringBuffer yerine tercih edilmelidir.
  2. Modern Java derleyicileri, okunabilir String birleştirmeyi uygun olduğunda sizin için optimize edilmiş bayt koduna dönüştürecektir.

3
Birincisi: Neden en az Java 5 kullanmayasınız? İkincisi: Evet yapabilirsin. Nasıl oluyor da ilk örnekte 5'e kadar sayabiliyorsunuz ama ikincisinde değil? İlk olarak aynı String değişmezlerini kullanır. Okunabilir kod yazın ve derleyicinin StringBuffer'ı perde arkasında ne zaman kullanacağına karar vermesine izin verin.
Bill the Lizard

4
@ MetroidFan2002: İkinci örnekteki String değişmez değerleri de nesnelerdir. Cevapta söylediğim gibi, bu ölçekte farklılıklar önemsiz.
Bill the Lizard

1
Bu, her String'i kendi StringBuffer ile değiştirdiği anlamına gelmez. Derleyicinin gerçekleştirdiği optimizasyon, oluşturulan nesnelerin sayısını azaltır.
Kertenkele Bill

3
@Eric: String msg = "Count =" + count + "of" + total + "."; genellikle Java'da String msg = new StringBuffer (). append ("Count"). append (count) .append ("of") .append (toplam) .append ("."). toString (); ... ikinci örneğin yaptığı da tam olarak budur.
Grant Wagner

3
Bay Wagner, derleyiciye değil, tüm bu yöntem çağrılarına SİZİN bakmanız gerektiğidir. Onları yazmalı ve daha sonra anlamalısın. Derleyici yine de aynı şeyi yapar. Dolayısıyla bu durumda okunabilirlik daha önemlidir.
ypnos

47

Bir keresinde 'Kök' tablosu kullanan bir MSSQL veritabanı görmüştüm. Kök tablosunun dört sütunu vardı: GUID (benzersiz tanımlayıcı), ID (int), LastModDate (datetime) ve CreateDate (datetime). Veritabanındaki tüm tablolar Kök tabloya Yabancı Anahtarlı idi. Veritabanındaki herhangi bir tabloda yeni bir satır oluşturulduğunda, ilgilendiğiniz gerçek tabloya ulaşmadan önce Kök tablosuna bir giriş eklemek için birkaç saklı yordam kullanmanız gerekir (bunun için işi yapan veritabanı yerine) birkaç tetikleyici basit tetikleyici ile).

Bu, işe yaramaz bir kulak misafiri ve baş ağrısı karmaşası yarattı, üzerine yazılan herhangi bir şeyin dişlileri kullanmasını gerektirdi (ve LINQ'i şirkete tanıtma umudumu ortadan kaldırdı. Mümkündü ama baş ağrısına değmezdi) ve üstesinden gelmek de değildi '' Yapması gerekeni bile başarmak.

Bu yolu seçen geliştirici, tabloların kendisinde Kılavuzları kullanmadığımız için bunun tonlarca alan tasarrufu sağladığını varsayarak savundu (ancak ... yaptığımız her satır için Kök tablosunda bir GUID oluşturulmadı mı?) , bir şekilde iyileştirilmiş performans ve veritabanındaki değişikliklerin denetlenmesini "kolaylaştırdı".

Oh, ve veritabanı diyagramı cehennemden gelen mutant bir örümceğe benziyordu.


42

Peki ya POBI - açıkça kasıtlı kötümseme?

90'lı yıllardaki meslektaşım, CEO'nun her ERP yazılımı (özel bir yazılım) sürümünün ilk gününü yeni işlevlerdeki performans sorunlarını bulmakla geçirdiği için CEO tarafından kıçına tekme atılmasından yorulmuştu. Yeni işlevler gigabaytları sıkıştırıp imkansızı mümkün kılmış olsa bile, her zaman üzerine sızlanacak bazı ayrıntılar ve hatta görünüşte önemli bir sorun buldu. Programlama hakkında çok şey bildiğine inanıyordu ve programcı kıçlarını tekmeleyerek tekmeledi.

Eleştirinin yetersiz doğası nedeniyle (o bir BT adamıydı, bir CEO'ydu), meslektaşım hiçbir zaman doğru anlayamadı. Performans probleminiz yoksa ortadan kaldıramazsınız ...

Bir sürüm için, yeni koda çok sayıda Gecikme (200) işlev çağrısı (Delphi idi) koydu. Yayına alındıktan sonra sadece 20 dakika sürdü ve gecikmiş hakaretlerini şahsen almak için CEO'nun ofisinde görünmesi emredildi.

Şimdiye kadarki tek alışılmadık şey, meslektaşlarım döndüğünde, gülümsediğinde, şakalaşarak, bir ya da iki BigMac için dışarı çıktığında sessiz kalmasıydı, bu sırada normalde masaları tekmeliyor, CEO ve şirket hakkında alevleniyor ve günün geri kalanını ölüme terk ederek geçiriyordu. .

Doğal olarak, meslektaşım şimdi bir veya iki gün masasında dinlendi, Quake'de nişan alma becerilerini geliştirdi - sonra ikinci veya üçüncü günde Gecikme çağrılarını sildi, yeniden inşa etti ve duyurduğu bir "acil durum yaması" yayınladı. performans açıklarını düzeltmek için 2 gün 1 gece geçirdiğini söyledi.

Bu, kötü CEO'nun "harika iş" dediği ilk (ve tek) zamandı! ona. Önemli olan bu, değil mi?

Bu gerçek POBI idi.

Ama aynı zamanda bir tür sosyal süreç optimizasyonu, bu yüzden% 100 sorun değil.

Bence.


10
"Lite" ın saniyede yalnızca birkaç veri kümesini, "süper süper" sürüm binlercesini yakalayabildiği farklı seviyelerde satılan bir veri işleme uygulaması hakkında birisinin yazdığını hatırlıyorum. Tek kaynak kod farkı Uyku (N) 'lardır.
peterchen

1
Parlak! Böyle bir durumda bu standardı tavsiye ederim. Geliştirmenin başlangıcında, büyük bir bellek parçası ayırın ve bazı uyku çağrıları ekleyin ve ne zaman biraz performans beklemeniz gerekiyorsa, onları kısın. Buna mucize işçi olmak deniyor;)
RCIX

Ne yazık ki, Sleeps'i NOP'lara yamalamak kolaydır, böylece lite sürümü çok kolay kırılabilir. Bu "optimizasyon" rezervi, hata ayıklama ve yama işlemini daha zor hale getirmek için yürütülebilir bir paketleyici gerektirebilir.
TheBlastOne

32

"Veritabanı Bağımsızlığı". Bu, saklanan hiçbir işlem, tetikleyici vb. Anlamına gelmiyordu - herhangi bir yabancı anahtar bile.


8
Bu, veri tabanından bu kadar yukarıda olmanız, verilerin ne olduğunu unutmanız anlamında mı "bağımsızlık"? Veri tabanları üzerinden gereksiz yere soyutlama yapmak, "göç ağrılarını önlemek için" çok basittir; buna ihtiyacın olmayacak.
Rob

8
Hemen hemen. Mimari astronotlar iş başında. Web varolduğundan beri web uygulamaları geliştiriyorum ve tüm bu zaman boyunca aslında bir db platformundan diğerine geçmedim.
chris

5
Eminim olur, ancak mimarinizi bu olasılık etrafında tasarlarsanız, aptal olmanız yeterince nadirdir.
chris

6
harpo, bu farklı bir durum - bu durumda bir gereklilik. Bunun bir gereklilik olmadığından bahsediyorum, ancak AA bir noktada bunun "olabileceğine" karar veriyor.
chris

3
@Tümü: DB bağımsızlığı size mal olabilir, evet, ancak ürünümüz DB satıcısının teklifler tarafından seçildiği ortamlarda çalışıyor ve temelde birlikte hareket etmemiz gerekiyor. Bazı geliştiriciler, dikey olarak entegre edilmiş bir yazılım yığını lüksüne sahip değiller ve buna rağmen bunu yapmak zorunda kalıyorlar.
Chris R

31
var stringBuilder = new StringBuilder();
stringBuilder.Append(myObj.a + myObj.b + myObj.c + myObj.d);
string cat = stringBuilder.ToString();

Şimdiye kadar gördüğüm en iyi StringBuilder kullanımı.


9
"Konsept belirsiz" hakkında konuşun! Vaov!
Eddie

3
Güzel. "Liderim dizeleri birleştirmek istiyorsam StringBuilder sınıfını kullanmam gerektiğini söylüyor. Ben de öyle yapıyorum. Peki sorun ne?" Lol ...
TheBlastOne

26

Basit bir dize.split yeterli olduğunda bir dizeyi bölmek için bir normal ifade kullanma


25
AMA Java'da String.Split bir regex kullanır!
Frank Krueger

Bir Regex'in dahili bir string split kadar hızlı olabileceğini anlamıyorum.
Andrei Rînea

2
Ancak, dizeyi bölmek için kullanılan bir normal ifadeyi kasıtlı olarak aramak ve onu 'basit' bir bölme işleviyle değiştirmek, mükemmel bir kötümseme örneği gibi geliyor. Regex kitaplıkları yeterince hızlıdır.
David Crawshaw

5
@David Crawshaw: Mikro optimizasyon fırsatlarını araştırmak insan zamanını boşa harcar; Tomurcuk yazma kodu, en az karmaşık yeterli çözümü kullanın.
Piskvor

6
-1: Eğer normal ifadelere alışkınsanız, 1001 dil-dahili dize manipülatörlerine alışmak yerine bunu yazmak çok doğaldır.
KillianDS

26

Biliyorum bu konuya çok geç, ama bunu yakın zamanda gördüm:

bool isFinished = GetIsFinished();

switch (isFinished)
{
    case true:
        DoFinish();
        break;

    case false:
        DoNextStep();
        break;

    default:
        DoNextStep();
}

Biliyor musun, bir mantıksal değerin bazı ekstra değerleri olması durumunda ...


22
True, False an FileNotFound ofcourse
Ikke

Hey, her zaman bir varsayılan / durumunuz olmalı, else / etc. Zeki bir kişi o boole'yi başka bir durumu yansıtmak için bir enum olarak değiştirdiğinde, sonraki kişi sıralamaya ekler ve prosedürü değiştirmeyi unutursa ne olur? Yürütme süresine ve çok az geliştirme süresine mal olmanız gerekmediğinde bir varsayılana sahip olmak. Çalışma sırasında meydana gelen, yanlışlıkla ortaya çıkan mantıksal bir hatanın izini sürmek ... Bu zaman, para ve itibar kaybına neden olur. Zaman içinde bir dikiş dokuz kaydeder.
Oorang

1
@Oorang ... neden yine de anahtar olarak sahip olasın? Bu bir boole - tek gereken bir if / else.
Damovisa

@Damovisa facepalm sağ ... çok iyi o zaman :) Bunu kaçırdım :)
Oorang

2
Nullable <Boolean> idi ... :)
George Chakhidze

25

Aklıma gelen en kötü örnek, şirketimdeki tüm çalışanlar hakkında bilgi içeren dahili bir veritabanıdır. İK'dan her gece bir güncelleme alır ve üstte bir ASP.NET web hizmeti vardır. Diğer birçok uygulama, arama / açılır alanlar gibi şeyleri doldurmak için web hizmetini kullanır.

Kötümserlik, geliştiricinin, web servisine yapılan tekrarlanan çağrıların, tekrarlanan SQL sorguları yapmak için çok yavaş olacağını düşünmesidir. Peki o ne yaptı? Uygulama başlatma olayı tüm veritabanını okur ve hepsini bellekteki nesnelere dönüştürür, uygulama havuzu geri dönüştürülene kadar süresiz olarak depolanır. Bu kod o kadar yavaştı ki 2000'den az çalışanda yüklenmesi 15 dakika sürerdi. Uygulama havuzunu gün içinde yanlışlıkla geri dönüştürdüyseniz, her web hizmeti isteği birden çok eşzamanlı yeniden yüklemeyi başlatacağından 30 dakika veya daha uzun sürebilir. Bu nedenle, yeni işe alınan kişiler, hesaplarının oluşturulduğu ilk gün veritabanında görünmez ve bu nedenle, çoğu dahili uygulamaya ilk birkaç gününde parmaklarını çevirerek erişemezler.

İkinci kötümserlik seviyesi, geliştirme yöneticisinin bağımlı uygulamaları bozma korkusuyla ona dokunmak istememesidir, ancak yine de böylesine basit bir bileşenin zayıf tasarımı nedeniyle şirket genelinde kritik uygulamalarda ara sıra kesintiler yaşamaya devam ediyoruz.


28
En iyi şekilde yönetim - "Hayır, bu uygulamayı düzeltmek için bir kereye mahsus 80 programcı saatini harcamayalım, bu çok pahalı. Hatalarının ayda 200+ kullanıcı saatini, ayrıca ayda 10 programcı saatini 'bakım'." AAAAAAAAAUGH !!!
Piskvor

25

Görünüşe göre kimse sınıflandırmadan bahsetmemiş, ben de söyleyeceğim.

Birkaç kez, birinin el yapımı bir balonlar sıralaması yaptığını keşfettim, çünkü durum zaten var olan "çok süslü" hızlı sıralama algoritmasına bir çağrı "gerektirmiyordu". Geliştirici, kendi el yapımı baloncukları test etmek için kullandıkları on veri satırı üzerinde yeterince iyi çalıştığında memnun oldu. Müşteri birkaç bin satır ekledikten sonra pek iyi gitmedi.


2
Tipik olarak n = 2 olduğunu belirlediğimde bunu bir kez kendim yaptım. Daha sonraki ürün geliştirmeleri benim önermemi geçersiz kıldı ve kod PDQ'nun yerini aldı.
Mark Ransom

2
Evet, ama arada bir algoritmaya dayalı bir şeyler yazmak güzel ;)
UpTheCreek

20

Bir keresinde bunun gibi kodlarla dolu bir uygulama üzerinde çalıştım:

 1 tuple *FindTuple( DataSet *set, int target ) {
 2     tuple *found = null;
 3     tuple *curr = GetFirstTupleOfSet(set);
 4     while (curr) {
 5         if (curr->id == target)
 6             found = curr;
 7         curr = GetNextTuple(curr);
 8     }
 9     return found;
10 }

Basitçe kaldırarak found, nullsonunda geri dönerek ve altıncı satırı şu şekilde değiştirerek:

            return curr;

Uygulama performansını iki katına çıkardı.


1
Bir kez kodlama yönergelerinin "sonunda yalnızca bir geri dönüş" (bakım için) talep ettiği bir şirkette çalıştım. Ve gerçekten de bazıları sizinki gibi kodlar tükürür, çünkü düşünmezler (bariz çözümler çoğu zaman proc çıkışına gitmek ya da döngülerin çıkış koşullarını değiştirmektir)
flolo

12
Buradaki bir dönüş akımı, oldukça farklı davranışlar üretir. Akım döndürdüğünüzde İLK eşleşmeyi elde edersiniz, burada yapıştırdığınız kod SON eşleşmeyi döndürür.
SoapBox

2
@SoapBox: Haklısın. @Dour High Arch: Flolo, döngü koşulunu (curr &&! Found) olarak değiştirmenin de aynı etkiye sahip olacağını söylediği için, performanstaki artışın tek dönüş kuralıyla ilgisi yoktu. Proc çıkışına GOTO korkunç ve tek dönüş kılavuzunun amacını bozuyor.
Akusete

2
Herkese iyi yorumlar. Bu durumda, her kimliğe sahip yalnızca tek bir demet olması gerekiyordu.
Dour Yüksek Arch

7
Bu bir "Pessimization" değil, değil mi? Bu sadece gerçekleşmeyi bekleyen bir optimizasyondur.
Tim Long

20

Bir keresinde Constants sınıfında bu mücevherleri içeren kodu değiştirmeye çalışmak zorunda kaldım

public static String COMMA_DELIMINATOR=",";
public static String COMMA_SPACE_DELIMINATOR=", ";
public static String COLIN_DELIMINATOR=":";

Bunların her biri, uygulamanın geri kalanında farklı amaçlar için birden çok kez kullanıldı. COMMA_DELIMINATOR, kodu 8 farklı pakette 200'den fazla kullanımla doldurdu.


En azından böyle bir şeyin kaynağından kolayca Bulunması / Değiştirilmesi - yine de sempati duyuyorum.
Erik Forbes

12
Ayrıca - Sınırlayıcı mı? "Sınırlayıcı" olarak yazıldığını sanıyordum. Deliminator, 90'ların ortalarında bir şekilde 3 sekans alan kötü bir film gibi geliyor ...........
Erik Forbes

53
Sınırlandırıcı III: Virgüllerin Yükselişi
Rob

33
Başka bir kayda göre, Colins'in doğru şekilde sınırlandırıldığını görmekten memnunum. Tuzuna değecek her programcı bilir ki, kesinlikle doğru bir şekilde ayırmanız gereken bir şey varsa, o da lanet Colins'dir.
Rob

2
Düzgün bir bulup değiştirmek o kadar kolay değil. Her biri farklı amaçlar için kullanıldığından. Herhangi bir iyi programcı en azından böyle bir şey yapardı: COUNTRY_LIST_DELIM = ... CLASSIFICATION_DELIM = ... etc
KitsuneYMG

19

Şirket içi yazılımda tekrar tekrar karşılaştığım tüm zamanların en büyüğü:

"Daha sonra başka bir satıcıya geçmek isteyebileceğimiz için" "taşınabilirlik" nedenleriyle DBMS'nin özelliklerini kullanmamak.

Dudaklarımı oku. Herhangi bir kurum içi çalışma için: OLMAYACAKTIR!


9
Olur. MySQL -> postgresql, yani hiçbir şey kaybetmedik .
Thomas

Veya postgres / postgis -> sqlite / spatialite ... Bu baş belasıydı ...
Philip

JUnit testlerinde oluyor
kachanov

17

C derleyicimizin optimize edicisini alt etmeye ve sadece onun okuyabileceği rutin kodu yeniden yazmaya çalışan bir iş arkadaşım vardı. En sevdiği püf noktalarından biri, okunabilir bir yöntemi değiştirmekti (bazı kodlar oluşturmak):

int some_method(int input1, int input2) {
    int x;
    if (input1 == -1) {
        return 0;
    }
    if (input1 == input2) {
        return input1;
    }
    ... a long expression here ...
    return x;
}

bunun içine:

int some_method() {
    return (input == -1) ? 0 : (input1 == input2) ? input 1 :
           ... a long expression ...
           ... a long expression ...
           ... a long expression ...
}

Yani, bir kez okunabilir bir yöntemin ilk satırı " return" olur ve diğer tüm mantık, derinlemesine iç içe geçmiş üçlü ifadelerle değiştirilir. Bunun nasıl sürdürülemez olduğunu tartışmaya çalıştığınızda, yönteminin montaj çıktısının üç veya dört montaj talimatının daha kısa olduğu gerçeğine işaret ederdi. Daha hızlı değildi ama her zaman küçücüktü biraz daha kısa. Bu, bellek kullanımının ara sıra önemli olduğu gömülü bir sistemdi, ancak kodu okunabilir bırakacak şekilde yapılabilecek daha kolay optimizasyonlar vardı.

Sonra, bundan sonra, bir nedenden ötürü, ptr->structElementbunun çok okunamaz olduğuna karar verdi , bu yüzden tüm bunları (*ptr).structElement, daha okunabilir ve daha hızlı olduğu teorisine dönüştürmeye başladı .

Okunabilir kodu, en fazla% 1'lik bir iyileştirme ve bazen daha yavaş kod için okunamaz koda dönüştürmek.


Söz konusu modül döngü başına milyonlarca ve milyonlarca kez çağrılıyorsa, o zaman bu optimizasyonu onun hakkında yorum yaptığı sürece onaylarım.
Michael Dorgan

2
@Michael: Sadece daha kısa değil , daha hızlı olduğunu gösteren ölçümler olmadıkça yapmam .
dsimcha

Çoğu durumda üçlü operatör, daha okunabilirdir if. C ifadeler üzerinde tablolarda ısrar kültürel / dini dogma olduğunu değil objektif uygulama her türlü. (Daha iyi bir kılavuz: Eğer iç içe geçmiş üçlü okumak için çok uzunsa, ifikisini de kullanmamalısınız .)
Leushenko

2
Buradaki mesele, tüm bir işlevi alıp onu tek bir deyimle, bir dönüşle değiştirerek, tüm işlevin tüm mantığını iç içe geçmiş üçlülerle değiştirmektir. Eğer görseydin, anlardın. Bu dinsel bir "üçlü operatörlerden nefret ediyorum" meselesi değil. ifBir işlevde bir single alıp onu üçlü ile değiştirmekten bahsetmiyorum . Bu iyi ve genellikle daha okunabilir. 30+ satır yönteminin tamamını tek bir dönüş ifadesi ve iç içe geçmiş üçlülerle değiştirmekten bahsediyorum. Hiç kimse yeni kodun daha okunabilir olduğunu düşünmedi, ancak bir geliştirici daha hızlı olduğunu düşündü.
Eddie

15

Tam teşekküllü bir geliştirici olarak ilk işlerimden birinde, ölçeklendirme sorunları olan bir program için bir projeyi devraldım. Küçük veri kümelerinde oldukça iyi çalışır, ancak büyük miktarlarda veri verildiğinde tamamen çökebilir.

Araştırdığımda, orijinal programcının analizi paralel hale getirerek her ek veri kaynağı için yeni bir iş parçacığı başlatarak işleri hızlandırmaya çalıştığını gördüm. Ancak, tüm iş parçacıklarının kilitlendiği paylaşılan bir kaynak gerektirdiği için bir hata yapmıştı. Elbette eşzamanlılığın tüm faydaları ortadan kalktı. Dahası, çoğu sistemi yalnızca biri hariç tümü kilitlemek için 100'den fazla iş parçacığı başlatmak için çöktü. Benim etli dev makinem, yaklaşık 6 saat içinde 150 kaynaklı bir veri kümesinden geçmesi açısından bir istisnaydı.

Bu yüzden düzeltmek için, çok iş parçacıklı bileşenleri çıkardım ve G / Ç'yi temizledim. Başka hiçbir değişiklik yapılmadan, 150 kaynaklı veri setindeki yürütme süresi makinemde 10 dakikanın altına ve ortalama şirket makinesinde sonsuzdan yarım saatin altına düştü.


Ben sadece bugün bir projede bunun olmasını önledim. Şimdi iyi bir seçim yaptığımı biliyorum.
deadalnix

14

Sanırım bu mücevheri sunabilirim:

unsigned long isqrt(unsigned long value)
{
    unsigned long tmp = 1, root = 0;
    #define ISQRT_INNER(shift) \
    { \
        if (value >= (tmp = ((root << 1) + (1 << (shift))) << (shift))) \
        { \
            root += 1 << shift; \
            value -= tmp; \
        } \
    }

    // Find out how many bytes our value uses
    // so we don't do any uneeded work.
    if (value & 0xffff0000)
    {
        if ((value & 0xff000000) == 0)
            tmp = 3;
        else
            tmp = 4;
    }
    else if (value & 0x0000ff00)
        tmp = 2;

    switch (tmp)
    {
        case 4:
            ISQRT_INNER(15);
            ISQRT_INNER(14);
            ISQRT_INNER(13);
            ISQRT_INNER(12);
        case 3:
            ISQRT_INNER(11);
            ISQRT_INNER(10);
            ISQRT_INNER( 9);
            ISQRT_INNER( 8);
        case 2:
            ISQRT_INNER( 7);
            ISQRT_INNER( 6);
            ISQRT_INNER( 5);
            ISQRT_INNER( 4);
        case 1:
            ISQRT_INNER( 3);
            ISQRT_INNER( 2);
            ISQRT_INNER( 1);
            ISQRT_INNER( 0);
    }
#undef ISQRT_INNER
    return root;
}

Karekök çok hassas bir yerde hesaplandığından, onu daha hızlı hale getirmenin bir yolunu bulma görevini aldım. Bu küçük yeniden düzenleme, yürütme süresini üçte bir oranında azalttı (kullanılan donanım ve derleyici kombinasyonu için, YMMV):

unsigned long isqrt(unsigned long value)
{
    unsigned long tmp = 1, root = 0;
    #define ISQRT_INNER(shift) \
    { \
        if (value >= (tmp = ((root << 1) + (1 << (shift))) << (shift))) \
        { \
            root += 1 << shift; \
            value -= tmp; \
        } \
    }

    ISQRT_INNER (15);
    ISQRT_INNER (14);
    ISQRT_INNER (13);
    ISQRT_INNER (12);
    ISQRT_INNER (11);
    ISQRT_INNER (10);
    ISQRT_INNER ( 9);
    ISQRT_INNER ( 8);
    ISQRT_INNER ( 7);
    ISQRT_INNER ( 6);
    ISQRT_INNER ( 5);
    ISQRT_INNER ( 4);
    ISQRT_INNER ( 3);
    ISQRT_INNER ( 2);
    ISQRT_INNER ( 1);
    ISQRT_INNER ( 0);

#undef ISQRT_INNER
    return root;
}

Elbette bunu yapmanın hem daha hızlı hem de daha iyi yolları var, ama bence bu oldukça düzgün bir karamsarlık örneği.

Düzenleme: Bir düşünün, açılmış döngü aslında aynı zamanda düzgün bir pessimizasyondu. Sürüm kontrolüne rağmen, yukarıdakilerden daha iyi performans gösteren yeniden düzenlemenin ikinci aşamasını da sunabilirim:

unsigned long isqrt(unsigned long value)
{
    unsigned long tmp = 1 << 30, root = 0;

    while (tmp != 0)
    {
        if (value >= root + tmp) {
            value -= root + tmp;
            root += tmp << 1;
        }
        root >>= 1;
        tmp >>= 2;
    }

    return root;
}

Bu, biraz farklı bir uygulama olsa da, tamamen aynı algoritmadır, bu yüzden uygun olduğunu düşünüyorum.


Sanırım isqrt()hesaplar floor(sqrt()), ama bu kod neden çalışıyor?
Pablo H

11

Bu, peşinde olduğunuzdan daha yüksek bir düzeyde olabilir, ancak düzeltmek (izin veriliyorsa) aynı zamanda daha yüksek düzeyde ağrı içerir:

Yerleşik, test edilmiş, olgun kitaplıklardan birini kullanmak yerine (size gösterildikten sonra bile) bir Nesne İlişkisi Yöneticisi / Veri Erişim Katmanı'nı el ile yuvarlamakta ısrar etmek.


Kendi kodunuzu döndürmek her zaman kötü bir fikir değildir. Bilge bir adamın dediği gibi, bağımlılıkları bulun ve ortadan kaldırın. Temel bir iş fonksiyonuysa, bunu kendiniz yapın.
Kibbee

Bunun her zaman kötü bir fikir olduğu sonucuna varmadım. Frans Bouma veya benzeri bir şey söylemediğiniz sürece, ORM / DAL şeylerinin temel bir iş işlevi olduğundan şüpheliyim. Genellikle NIH sendromu nedeniyle, (kare) tekerleği yeniden icat etme vakası olan kendi eşdeğeri yazmak son derece maliyetsizdir.
Gordon Hartley

@Kibbee - Katılıyorum. Üçüncü taraf bağımlılıklarını kullanmaktansa kendinizinkini almak ve anlamak daha iyidir. Kırıldığında (ve olacak) en azından o zaman düzeltebilirsin. Geçmişte Hibernate ve Apache Commons'ta, uygulamamızın performansını kesinlikle düşüren hatalar buldum.
CodingWithSpike

4
Yerleşik olanlardan hiçbiri ihtiyacınız olan kritik bir özelliğe sahip değilse, tek seçeneğiniz elle yuvarlamaktır.
staticsan

3
Aslında, yukarıdaki yorumların bazıları göz önüne alındığında, biraz daha perspektif: Başka bir kötümserlik, ORM'nin kesinlikle her şeyi yapmasını sağlamaktır. Genellikle vakaların% 95'i için faydalıdır. Bu son% 5 için performans, basitlik veya her ikisi için elle hazırlanmış kalıcılık koduna / doğrudan depolanmış prosedür çağrılarına vb. Bırakmak çok daha kolaydır.
Gordon Hartley

10

Tüm yabancı anahtar kısıtlamaları bir veritabanından kaldırıldı, çünkü aksi takdirde çok fazla hata olurdu.


8

Bu soruya tam olarak uymuyor, ancak yine de uyarıcı bir masaldan bahsedeceğim. Yavaş çalışan, dağıtılmış bir uygulama üzerinde çalışıyordum ve öncelikle sorunu çözmeyi amaçlayan bir toplantıya katılmak için DC'ye uçtum. Proje lideri, gecikmeyi çözmeyi amaçlayan bir yeniden mimariyi özetlemeye başladı. Hafta sonu boyunca darboğazı tek bir yöntemle izole eden bazı ölçümler yaptığıma gönüllü oldum. Yerel bir aramada eksik bir kayıt olduğu ortaya çıktı ve bu da uygulamanın her işlemde uzak bir sunucuya gitmesine neden oldu. Kaydı yerel mağazaya geri ekleyerek gecikme ortadan kaldırıldı - sorun çözüldü. Yeniden mimarinin sorunu çözmeyeceğini unutmayın.


8

HER javascript işleminden önce üzerinde çalıştığınız nesnenin var olup olmadığını kontrol etme.

if (myObj) { //or its evil cousin, if (myObj != null) {
    label.text = myObj.value; 
    // we know label exists because it has already been 
    // checked in a big if block somewhere at the top
}

Bu tür bir kodla ilgili sorunum, kimsenin umurunda değil, yoksa yoksa? Hiçbir şey yapmamak mı? Geri bildirimi kullanıcıya vermiyor musunuz?

Object expectedHataların can sıkıcı olduğuna katılıyorum , ancak bunun için en iyi çözüm bu değil.


O halde en iyi çözüm nedir? Bence, doğrudan sonuçları olmasa bile hataların ara sıra meydana geldiği yerlerde kod yazmanın özensiz olduğunu düşünüyorum. Elbette, nesnenin hiçbir koşulda boş olmasını beklemiyorsanız, bunu yapmamalısınız - belki de demek istediğiniz budur.
simon

7

YAGNI aşırılığına ne dersiniz? Erken bir kötümseme şeklidir. Görünüşe göre YAGNI'yi her uyguladığınızda, sonunda ona ihtiyaç duyuyorsunuz, bu da onu eklemek için başlangıçta eklemiş olmanıza kıyasla 10 kat daha fazla çaba sarf ediyor. Başarılı bir program yaratırsanız, o zaman büyük olasılıkla buna İHTİYACINIZ OLACAKTIR. Hayatı hızla biten programlar yaratmaya alışkınsanız, YAGNI'yi uygulamaya devam edin çünkü o zaman YAGNI olduğunu düşünüyorum.


3
Teşekkürler, bu 'aşırı programlama' kısaltmalarından ve insanların bunları tembel, üretken olmayan uygulamaları desteklemek için nasıl kullandıklarından bıktım.
JAL

Gerçek projeler üzerine yapılan araştırmalar, bir defalık ve yeniden kullanılabilir kod arasındaki gerçek faktörün ortalamasının yaklaşık 3 olduğunu göstermektedir. Yani 10 sadece "hissedilen" değerdir, ancak siz haklısınız.
peterchen

@peterchen - Eğer çalışmalar bu tek seferlik kodu olarak yeniden kod yazmak sürece üç kez alır, ya da o kadar uzun olduğu üç kez gerçekleştiğini gösteriyor gösteriyor söylüyoruz dönüştürmek o yazma için göre yeniden kullanılabilir kod tek seferlik-kodu ilk etapta yeniden kullanılabilir kod?
Jeff Sternal

@jeff: IIRC, ayrı yöntemlere taşınan satır içi snippet'lerin bazı karmaşıklık ölçülerini (onlar hakkında ne düşünürseniz düşünün) karşılaştırdılar. Desteklenen ek durumlar, parametre kontrolü vb. Nedeniyle karmaşıklık artıyor (bu da yöntemlerin oldukça küçük olduğunu varsaymamı sağlıyor). Bir referans bulmaya çalışayım.
peterchen

6

Tam olarak erken optimizasyon değil - ama kesinlikle yanlış yönlendirilmiş - bu, Windows 7'yi tartışan bir makaleden BBC web sitesinde okundu.

Bay Curran, Microsoft Windows ekibinin iyileştirmeler yapmak için işletim sisteminin her yönünü incelediğini söyledi. "WAV dosyası kapatma müziğini biraz kırparak kapanma süresini 400 milisaniye azaltmayı başardık.

Şimdi, Windows 7'yi henüz denemedim, bu yüzden yanılıyor olabilirim, ancak orada, kapatmanın ne kadar sürdüğünden daha önemli olan başka sorunlar olduğuna bahse girmeye hazırım. Sonuçta, 'Windows'u Kapat' mesajını gördüğümde, monitör kapanıyor ve uzaklaşıyorum - bu 400 milisaniye bana nasıl fayda sağlıyor?


Muhtemelen diğer konuların bir BBC web sitesinde programcı olmayanlara açıklanmasının kolay olmadığını göreceksiniz.
Tom Leys

Şimdi bu, dikkate almadığım bir açı - belki de
kinizmimi

Bu 400 ms, 400 ms güç çekimidir. Muhtemelen önemsizdir, ama belki zamanla artar. Yine de endişeleneceğim bir şey değil.
ZachS

1
Bir sonraki şeye geçebilmek için XP sanal makinelerinin kapanmasını beklerken toplamda çok fazla saat kaybettim. Daha hızlı kapanma için minnettarım.
James

1
İlginç bir şekilde, WAV dosyaları eşzamansız olarak oynatılır, bu nedenle kapatma fanfare, kapatma için gereken süreden daha kısa olduğu sürece, WAV dosyasını kırpmak hiçbir şey yapmaz. Ve daha da ilginci, kapatmayı çok optimize ettilerse, kapattığım her Windows kutusu gerçekten kapanana kadar nasıl oluyor da çok fazla ihtiyaç duyuyor? (Tabii ki büyük kırmızı düğmeyi kullanmak dışında.)
TheBlastOne

6

Bölümümden biri bir zamanlar bir string sınıfı yazdı. Gibi bir arayüzCStringWindows bağımlılığı olmayan .

Bir "optimizasyon" yaptılar oldu değil gerekenden daha fazla bellek ayrılamadı. Görünüşe göre sınıfların std::stringfazla bellek ayırmasının nedeninin bir dizi +=işlemin O (n) zamanında çalışabileceğinin farkında değiller .

Bunun yerine, her bir +=çağrı bir yeniden tahsisi zorladı ve bu tekrar tekrar bir O (n²) Schlemiel the Painter algoritmasına ekler .


5

Java ERP'miz için müşterilerin verilerini (perakende sektörü) toplaması ve analiz etmesi gereken yeni bir modül oluşturmak üzere eski bir iş arkadaşım ( aslında bir soab ) görevlendirildi. HER Takvim / Tarih-Saat alanını bileşenlerine (saniye, dakika, saat, gün, ay, yıl, haftanın günü, bimester, üç aylık dönem (!)) Ayırmaya karar verdi çünkü "'her pazartesi' için başka nasıl sorgulama yapardım?"


3
Bu erken bir optimizasyon değil, doğruluk için bunu yapması gerektiğini düşündü
Pyrolistical

Elbette, buna ihtiyacı olduğunu düşündü , ancak çoğu DBMS'nin bir tür DAYOFWEEK (zaman damgası) işlevi olduğundan, bu karışıklığı önceden yapmak benim görüşüme göre yeterince erken :)
Joril

1
OLTP için kullanmazdım, ancak "müşterinin verilerini analiz ediyorsanız", bu aslında bir veri ambarı tasarlamanın çok esnek bir yoludur (tarih ve saat farklı boyutlara bölündüğü sürece). Milyonlarca satırlık veriye karşı DAYOFWEEK () 'i gerçekten çağırmak ister miydiniz yoksa sadece bir tamsayı alanına karşı bir dizin araması mı yapmak istersiniz?
Tim Medora

Pekala, bu kadar çok satır olup olmadığını bilmiyorum, ama kesinlikle verilen açıklama bu değildi :)
Joril

3

Kimseye gücenme, ama buna sahip bir ödeve (java) not verdim

import java.lang.*;

1
Bu üst düzey bir sınıf olmadığı sürece, bunun neden iyi bir fikir olmadığını anlayacak kadar ona öğretmediyseniz, bu öğrenciyi biraz gevşetmeniz gerektiğini düşünüyorum.
Bryan Oakley

24
WTF'yi arayan bir öğretmenin, doğru programlamayı öğretmekle sorumlu olduğu öğrencinin koduna ilişkin ironisine dikkat çeken tek kişi ben miyim?
JohnFx

3
Evet, bunun acıtacağını göremiyorum. En kötüsü de surpurflu. Öğrenciler, öğrenirken katı tutarlılığa başvurma eğilimindedir ve java.lang dosyasını içe aktarmak, öğrencinin içe aktarma hakkında öğrendikleriyle katı bir şekilde tutarlıdır.
cygil

1
Bana apaçık olanı söylediğiniz için hepinize teşekkür ederim. Bu bir Hesaplamalı Biyoloji ödeviydi ve onu saymadım, hatta bahsetmedim.
overflown

2
@JohnFX: Not veren ve öğretmen her zaman aynı kişi değildir.
Eddie
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.