Apa pesimisasi paling konyol yang pernah Anda lihat? [Tutup]

145

Kita semua tahu bahwa optimasi prematur adalah akar dari semua kejahatan karena mengarah pada kode yang tidak dapat dibaca / tidak dapat dipelihara. Yang lebih buruk adalah pesimisasi, ketika seseorang mengimplementasikan "optimisasi" karena mereka pikir itu akan lebih cepat, tetapi akhirnya menjadi lebih lambat, serta menjadi buggy, tidak dapat dipelihara, dll. Apa contoh paling konyol dari hal ini yang pernah Anda lihat ?

dsimcha
sumber
21
"Pesimisasi" adalah kata yang bagus.
mqp
Kalau-kalau Anda tidak tahu, mereka berbicara tentang utas Anda di sini di podcast terbaru.
mmcdole

Jawaban:

81

Pada proyek lama kami mewarisi beberapa programmer sistem embedded (jika tidak unggul) yang memiliki pengalaman Z-8000 yang masif.

Lingkungan baru kami adalah Solaris 32-bit.

Salah satu dari mereka pergi dan mengubah semua int menjadi celana pendek untuk mempercepat kode kami, karena mengambil 16 bit dari RAM lebih cepat daripada mengambil 32 bit.

Saya harus menulis program demo untuk menunjukkan bahwa mengambil nilai 32-bit pada sistem 32-bit lebih cepat daripada mengambil nilai 16-bit, dan menjelaskan bahwa untuk mengambil nilai 16-bit, CPU harus membuat lebar 32-bit akses memori dan kemudian tutup atau geser bit yang tidak diperlukan untuk nilai 16-bit.

Mark Harrison
sumber
16
Hei darimana kamu belajar matematika? 2 instruksi dengan 1 cache / akses RAM jelas lebih cepat dari 1 instruksi dengan 1 cache / akses RAM!
Razor Storm
2
@ RazorStorm Pada mesin yang lebih baru di mana bandwidth dan cache lebih berharga, yang terjadi adalah sebaliknya. Bitmask / shift murah, tetapi Anda ingin memuat sebanyak mungkin dalam cache dan juga meminimalkan bandwidth.
Jed
206

Saya pikir ungkapan "optimisasi prematur adalah akar dari semua kejahatan" adalah cara, cara yang terlalu sering digunakan. Bagi banyak proyek, menjadi alasan untuk tidak mempertimbangkan kinerja sampai terlambat dalam suatu proyek.

Ungkapan ini seringkali merupakan penopang bagi orang untuk menghindari pekerjaan. Saya melihat frasa ini digunakan ketika orang harus benar-benar mengatakan "Wah, kami benar-benar tidak memikirkan itu di muka dan tidak punya waktu untuk menghadapinya sekarang".

Saya telah melihat lebih banyak contoh "konyol" masalah kinerja bodoh daripada contoh masalah yang diperkenalkan karena "pesimisasi"

  • Membaca ribuan kunci registri yang sama (atau 10 dari ribuan) kali selama peluncuran program.
  • Memuat DLL yang sama ratusan atau ribuan kali
  • Memboroskan mega byte memori dengan menjaga jalur penuh ke file tidak perlu
  • Tidak mengatur struktur data sehingga mereka mengambil lebih banyak memori daripada yang mereka butuhkan
  • Mengubah ukuran semua string yang menyimpan nama atau jalur file ke MAX_PATH
  • Polling gratis untuk hal yang memiliki acara, panggilan balik atau mekanisme pemberitahuan lainnya

Apa yang saya pikir adalah pernyataan yang lebih baik adalah ini: "optimasi tanpa mengukur dan memahami bukan optimasi sama sekali - hanya perubahan acak".

Kinerja yang baik adalah pekerjaan yang memakan waktu - seringkali lebih untuk pengembangan fitur atau komponen itu sendiri.

Foredecker
sumber
46
"Premature" adalah kata kunci dari kutipan itu. Pengulangan Anda menjadi "optimisasi tanpa mengukur dan memahami" tampaknya tidak mengubah sedikit pun makna. Itulah yang dimaksud Knuth.
Bill the Lizard
13
@Foredecker: tepat. Terlalu banyak orang lupa konteksnya, yang menempatkan kutipan itu dengan kuat menentang optimasi mikro . Menganalisis masalah untuk memilih algoritma yang tepat sebelum mengimplementasikannya bukan prematur, namun terlalu sering kutipan itu dilontarkan untuk membenarkan solusi paling malas dan paling tidak efisien.
Shog9
5
Itu benar-benar tergantung pada kasus individual, ada lebih banyak kasus di mana optimasi prematur menjadi masalah, daripada perencanaan optimasi yang tidak memadai menjadi masalah
Mark Rogers
12
-1: Ada perbedaan antara "optimasi" dan desain yang tepat. Bagi mereka yang tidak tahu, aturan praktis yang baik adalah bahwa "optimasi" membuat kode lebih sulit untuk dibaca, tetapi lebih cepat atau lebih efisien. Desain yang lebih baik akan membuat kode lebih mudah dibaca (atau setidaknya tidak lebih buruk) dan lebih efisien.
TED
5
Jika cara ini terlalu sering digunakan, maka populasi yang mengajukan pertanyaan pada SO sangat terbebani terhadap outlier. : D
dkretz
114

Basis data adalah pesimisasi playland.

Favorit meliputi:

  • Pisahkan tabel menjadi beberapa (berdasarkan rentang tanggal, rentang alfabet, dll.) Karena "terlalu besar".
  • Buat tabel arsip untuk catatan yang sudah pensiun, tetapi lanjutkan UNION dengan tabel produksi.
  • Gandakan seluruh basis data dengan (divisi / pelanggan / produk / dll.)
  • Menolak menambahkan kolom ke indeks karena membuatnya terlalu besar.
  • Buat banyak tabel ringkasan karena penghitungan ulang dari data mentah terlalu lambat.
  • Buat kolom dengan subbidang untuk menghemat ruang.
  • Denormalkan ke dalam bidang-sebagai-an-array.

Itu di atas kepala saya.

le dorfier
sumber
Menolak kebutuhan untuk mengindeks hanya menyakitkan untuk dipikirkan.
Bill the Lizard
2
Ya, saya kenal seseorang yang bekerja untuk perusahaan minyak AS yang besar di mana hampir semua meja mereka memiliki tabel arsip terkait, dan sebagian besar kueri memilih dari tampilan yang menyatukan pasangan tabel. Performa seperti yang Anda harapkan!
Tony Andrews
Hah, saya pikir setiap DBA pasti sudah turun serikat dengan rute tabel arsip di beberapa titik. Ini selalu tampak begitu wajar pada saat itu.
Cruachan
3
Saya menambahkan: membagi database dalam beberapa basis data yang berbeda (pelanggan ac, pelanggan df, dll.)
Gabriele D'Antona
Bisakah Anda menguraikan "Denormalkan ke dalam bidang-sebagai-an-array."? Apa maksudmu disini?
Bart van Heukelom
87

Saya pikir tidak ada aturan mutlak: beberapa hal yang terbaik dioptimalkan dimuka, dan beberapa tidak.

Misalnya, saya bekerja di perusahaan tempat kami menerima paket data dari satelit. Setiap paket menghabiskan banyak uang, sehingga semua data sangat dioptimalkan (mis. Dikemas). Misalnya, lintang / bujur tidak dikirim sebagai nilai absolut (mengapung), tetapi sebagai offset relatif terhadap sudut "barat laut" dari zona "saat ini". Kami harus membongkar semua data sebelum dapat digunakan. Tapi saya pikir ini bukan pesimisasi, ini adalah optimasi cerdas untuk mengurangi biaya komunikasi.

Di sisi lain, arsitek perangkat lunak kami memutuskan bahwa data yang tidak dibongkar harus diformat menjadi dokumen XML yang sangat mudah dibaca, dan disimpan dalam basis data kami (sebagai lawan setiap bidang disimpan dalam kolom yang sesuai). Gagasan mereka adalah "XML adalah masa depan", "ruang disk murah", dan "prosesor murah", jadi tidak perlu mengoptimalkan apa pun. Hasilnya adalah bahwa paket 16-byte kami diubah menjadi dokumen 2kB yang disimpan dalam satu kolom, dan bahkan untuk pertanyaan sederhana kami harus memuat megabyte dokumen XML dalam memori! Kami menerima lebih dari 50 paket per detik, sehingga Anda dapat membayangkan betapa mengerikannya kinerja (BTW, perusahaan bangkrut).

Jadi sekali lagi, tidak ada aturan absolut. Ya, terkadang optimasi terlalu dini adalah kesalahan. Tapi terkadang motto "cpu / disk space / memory is cheap" adalah akar sebenarnya dari semua kejahatan.

MiniQuark
sumber
37
Saya setuju "cpu / ruang disk / memori murah" adalah akar sebenarnya dari semua kejahatan. +1
ksuralta
5
Saya pernah mendengar bahwa XML drivel juga. Perusahaan mabuk lainnya.
n8wrl
19
@ksuralta: "Cpu / ruang disk / memori murah" adalah alasan yang mudah untuk menghindari pemikiran. Menghindari pikiran adalah akar khayalan dari semua kejahatan.
Piskvor meninggalkan gedung
XMLisasi ini juga terjadi di tempat kerja saya, diikuti oleh JSONisasi. Semua untuk menghindari beberapa desain database relasional "melelahkan".
Tanz87
75

Ya Tuhan, kurasa aku telah melihat semuanya. Lebih sering daripada tidak itu merupakan upaya untuk memperbaiki masalah kinerja oleh seseorang yang terlalu malas untuk memecahkan masalah mereka hingga PENYEBAB masalah kinerja tersebut atau bahkan meneliti apakah sebenarnya ada masalah kinerja. Dalam banyak kasus ini saya bertanya-tanya apakah itu bukan hanya kasus orang yang ingin mencoba teknologi tertentu dan mati-matian mencari paku yang sesuai dengan palu baru mereka yang mengkilap.

Berikut ini contoh terbaru:

Arsitek data datang kepada saya dengan proposal yang rumit untuk mempartisi tabel kunci secara vertikal dalam aplikasi yang cukup besar dan kompleks. Dia ingin tahu jenis upaya pengembangan apa yang diperlukan untuk menyesuaikan perubahan. Percakapan berlangsung seperti ini:

Saya: Mengapa Anda mempertimbangkan ini? Apa masalah yang Anda coba selesaikan?

Dia: Tabel X terlalu luas, kami mempartisi untuk alasan kinerja.

Aku: Apa yang membuatmu berpikir itu terlalu lebar?

Dia: Konsultan mengatakan terlalu banyak kolom dalam satu tabel.

Saya: Dan ini mempengaruhi kinerja?

Dia: Ya, pengguna telah melaporkan pelambatan berselang di modul XYZ aplikasi.

Saya: Bagaimana Anda tahu lebar tabel adalah sumber masalahnya?

Dia: Itu adalah tabel kunci yang digunakan oleh modul XYZ, dan itu seperti 200 kolom. Itu pasti masalahnya.

Saya (Menjelaskan): Tetapi modul XYZ secara khusus menggunakan sebagian besar kolom dalam tabel itu, dan kolom yang digunakannya tidak dapat diprediksi karena pengguna mengonfigurasi aplikasi untuk menampilkan data yang ingin ditampilkan dari tabel itu. Sangat mungkin bahwa 95% dari waktu kita akhirnya bergabung dengan semua tabel kembali bersama yang akan merusak kinerja.

Dia: Konsultan mengatakan itu terlalu luas dan kita perlu mengubahnya.

Saya: Siapa konsultan ini? Saya tidak tahu kami menyewa konsultan, juga tidak berbicara dengan tim pengembang.

Dia: Yah, kita belum mempekerjakan mereka. Ini adalah bagian dari proposal yang mereka tawarkan, tetapi mereka bersikeras kami perlu merancang kembali database ini.

Saya: Uh huh. Jadi konsultan yang menjual jasa desain ulang basis data berpikir kita memerlukan desain ulang ...

Percakapan terus berlanjut seperti ini. Setelah itu, saya melihat lagi tabel yang dimaksud dan memutuskan bahwa itu mungkin bisa dipersempit dengan normalisasi sederhana tanpa perlu strategi partisi yang eksotis. Ini, tentu saja ternyata menjadi titik diperdebatkan setelah saya menyelidiki masalah kinerja (sebelumnya tidak dilaporkan) dan melacaknya ke dua faktor:

  1. Indeks tidak ada pada beberapa kolom utama.
  2. Beberapa analis data jahat yang secara berkala mengunci tabel kunci (termasuk tabel "terlalu luas") dengan menanyakan database produksi secara langsung dengan MSAccess.

Tentu saja arsitek masih mendorong partisi vertikal dari tabel yang bergantung pada meta-masalah "terlalu lebar". Dia bahkan memperkuat kasusnya dengan mendapatkan proposal dari konsultan basis data lain yang dapat menentukan bahwa kami memerlukan perubahan desain besar pada basis data tanpa melihat aplikasi atau menjalankan analisis kinerja.

JohnFx
sumber
Aaag MSAccess ke prod. Kami menulis prosedur untuk menjatuhkan semua koneksi akses setiap beberapa menit dan akhirnya menemukan pesan bahwa itu buruk.
Nat
1
Kami memiliki pekerjaan yang serupa, tetapi tidak digunakan lagi. Agar adil, Access bukan masalah, itu hanya memudahkan bagi orang baru untuk membuat / menjalankan kueri yang tidak berkinerja.
JohnFx
Kami memiliki ketergantungan di perusahaan kami pada koneksi akses lama ad hoc ke DB produksi. Tidak ada yang seperti beberapa SQLer kasual untuk melupakan klausa WHERE dan kebuntuan tabel utama!
HardCode
35
"Saya mendengar lembayung muda memiliki RAM terbanyak"
Piskvor meninggalkan gedung
Itu bisa lebih buruk. Editor Kueri Excel mengunci basis data lengkap saat menggunakannya. Ketika saya tidak mengetahuinya, saya membiarkan satu contoh terbuka untuk bagian yang lebih baik dari hari sementara saya bekerja di sesuatu yang lain. Bagian terburuknya adalah MS SQL Server tidak melaporkan nama pengguna / mesin yang benar yang membuat kunci. Saya menyadari beberapa jam kemudian bahwa saya adalah alasan dari penguncian karena tabel dikunci menjadi bagian dari pandangan saya bertanya dan setelah memeriksa semuanya terlebih dahulu.
Esteban Küber
58

Saya telah melihat orang menggunakan alphadrive-7 untuk benar-benar menetaskan CHX-LT. Ini adalah praktik yang tidak biasa. Praktek yang lebih umum adalah menginisialisasi transformator ZT sehingga bufferication berkurang (karena resistensi overload bersih yang lebih besar) dan membuat bytegraphications gaya java.

Benar-benar pesimis!

Zalaga
sumber
10
mungkin mereka mencoba embiggen kapasitor fluks
Mikeage
6
Jadi, pada dasarnya satu-satunya prinsip baru yang terlibat adalah alih-alih tenaga yang dihasilkan oleh gerakan relatif konduktor dan fluks, yang dihasilkan oleh interaksi modial keengganan magneto dan duraktansi kapasitif?
Matt Rogish
17
1 karena monitor saya diperlukan membersihkan pula ;-)
RBerteig
1
Sial!! Tetapi bagaimana dengan efek ekletromagentik-lintas-genetika. Saya pikir itu harus dipertimbangkan juga. Atau subjek mungkin berubah menjadi zombie.
Suraj Chandran
1
Tiga kata: "Chrome Muffler Bearings."
Allbite
53

Tidak ada yang Menghancurkan Bumi, saya akui, tetapi saya telah menangkap orang menggunakan StringBuffer untuk menyatukan Strings di luar loop di Jawa. Itu sesuatu yang sederhana seperti berputar

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

ke

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

Ini dulunya merupakan praktik yang cukup umum untuk menggunakan teknik dalam satu lingkaran, karena itu terukur lebih cepat. Masalahnya, StringBuffer disinkronkan, jadi sebenarnya ada overhead tambahan jika Anda hanya menggabungkan beberapa Strings. (Belum lagi bahwa perbedaannya sangat sepele pada skala ini.) Dua poin lain tentang praktik ini:

  1. StringBuilder tidak disinkronkan, jadi harus lebih disukai daripada StringBuffer dalam kasus di mana kode Anda tidak dapat dipanggil dari banyak utas.
  2. Kompiler Java modern akan mengubah rangkaian String yang dapat dibaca menjadi bytecode yang dioptimalkan untuk Anda ketika itu sesuai.
Bill the Lizard
sumber
3
Pertama: Mengapa Anda tidak menggunakan setidaknya Java 5? Kedua: Ya, Anda bisa. Bagaimana Anda bisa menghitung sampai 5 pada contoh pertama, tetapi bukan yang kedua? Ia menggunakan String literal yang sama dengan yang pertama. Tulis kode yang dapat dibaca dan biarkan kompiler memutuskan kapan harus menggunakan StringBuffer di belakang layar.
Bill the Lizard
4
@ MetroidFan2002: String literal dalam contoh kedua adalah objek juga. Seperti yang saya katakan dalam jawaban, perbedaannya sepele pada skala ini.
Bill the Lizard
1
Itu tidak berarti itu menggantikan setiap String dengan StringBuffer sendiri. Optimalisasi yang dilakukan oleh kompiler mengurangi jumlah objek yang dibuat.
Bill the Lizard
3
@Eric: String msg = "Count =" + count + "of" + total + "."; sering dikompilasi dalam Java ke String msg = new StringBuffer (). append ("Count"). append (count) .append ("of") .append (total) .append ("."). toString (); ... yang persis seperti contoh kedua.
Grant Wagner
3
Tn. Wagner masalahnya adalah bahwa ANDA harus melihat semua pemanggilan metode ini, bukan kompiler. Anda harus menulis dan memahaminya nanti. Kompiler tetap melakukan hal yang sama. Jadi keterbacaan lebih penting dalam hal ini.
ypnos
47

Saya pernah melihat database MSSQL yang menggunakan tabel 'Root'. Tabel Root memiliki empat kolom: GUID (uniqueidentifier), ID (int), LastModDate (datetime), dan CreateDate (datetime). Semua tabel dalam database adalah Foreign Key'd ke tabel Root. Setiap kali baris baru diciptakan pada setiap tabel di db, Anda harus menggunakan beberapa prosedur tersimpan untuk memasukkan entri di tabel Root sebelum Anda bisa sampai ke tabel aktual yang Anda pedulikan (daripada database yang melakukan pekerjaan untuk Anda dengan beberapa pemicu pemicu sederhana).

Ini menciptakan kekacauan yang tidak sengaja dan sakit kepala yang tidak berguna, diperlukan apa pun yang tertulis di atasnya untuk menggunakan sprocs (dan menghilangkan harapan saya untuk memperkenalkan LINQ ke perusahaan. Itu mungkin tapi tidak sebanding dengan sakit kepala), dan to top it off tidak layak Bahkan tidak mencapai apa yang seharusnya dilakukan.

Pengembang yang memilih jalur ini mempertahankannya dengan asumsi bahwa ini menghemat banyak ruang karena kami sendiri tidak menggunakan Guids di tabel (tapi ... bukankah GUID dibuat di tabel Root untuk setiap baris yang kita buat?) , meningkatkan kinerja, entah bagaimana, dan membuatnya "mudah" untuk mengaudit perubahan pada basis data.

Oh, dan diagram database tampak seperti laba-laba mutan dari neraka.

Dusda
sumber
42

Bagaimana dengan POBI - pesimisasi jelas dengan niat?

Collegue milik saya di tahun 90-an bosan ditendang di pantat oleh CEO hanya karena CEO menghabiskan hari pertama dari setiap rilis perangkat lunak ERP (kustom) dengan menempatkan masalah kinerja dalam fungsi-fungsi baru. Bahkan jika fungsi-fungsi baru itu berderak gigabyte dan membuat yang tidak mungkin menjadi mungkin, ia selalu menemukan beberapa detail, atau bahkan masalah yang tampaknya besar, untuk dikeluhkan. Dia diyakini tahu banyak tentang pemrograman dan mendapatkan tendangannya dengan menendang pantat programmer.

Karena sifat kritik yang tidak kompeten (dia adalah CEO, bukan cowok IT), kolega saya tidak pernah berhasil melakukannya dengan benar. Jika Anda tidak memiliki masalah kinerja, Anda tidak dapat menghilangkannya ...

Sampai untuk satu rilis, ia menempatkan banyak panggilan fungsi Delay (200) (itu adalah Delphi) ke dalam kode baru. Butuh hanya 20 menit setelah ditayangkan, dan dia diperintahkan untuk muncul di kantor CEO untuk mengambil penghinaan tertunda secara langsung.

Hanya hal yang tidak biasa sejauh ini adalah kolega saya bisu ketika dia kembali, tersenyum, bercanda, pergi untuk satu atau dua BigMac sementara dia biasanya akan menendang meja, berbicara tentang CEO dan perusahaan, dan menghabiskan sisa hari berubah menjadi mati .

Secara alami, kolega saya sekarang beristirahat selama satu atau dua hari di mejanya, meningkatkan keterampilan membidik di Quake - kemudian pada hari kedua atau ketiga ia menghapus panggilan Penundaan, membangun kembali dan merilis "tambalan darurat" di mana ia menyebarkan berita bahwa dia telah menghabiskan 2 hari dan 1 malam untuk memperbaiki lubang kinerja.

Ini adalah pertama (dan satu-satunya) yang dikatakan CEO jahat "pekerjaan hebat!" untuk dia. Itu yang terpenting, bukan?

Ini adalah POBI asli.

Tapi itu juga semacam optimasi proses sosial, jadi 100% ok.

Kupikir.

TheBlastOne
sumber
10
Saya ingat seseorang menulis tentang aplikasi pengolah data yang dijual pada tingkat yang berbeda di mana "Lite" hanya dapat menghancurkan beberapa set data per detik, versi "superduper" ribuan. Satu-satunya perbedaan kode sumber adalah Sleep (N).
peterchen
1
Cemerlang! Saya akan merekomendasikan standar itu dalam situasi seperti itu. Pada awal pengembangan mengalokasikan sejumlah besar memori dan menambahkan beberapa panggilan tidur, dan setiap kali Anda perlu untuk mendapatkan beberapa kinerja, cukup selipkan mereka. Ini disebut sebagai pekerja ajaib;)
RCIX
Sayangnya, menambal Sleeps ke NOP mudah, sehingga versi lite dapat di-crack dengan mudah. Cadangan "optimisasi" ini mungkin memerlukan pengepak yang dapat dieksekusi untuk mempersulit proses debug dan menambal.
TheBlastOne
32

"Kemerdekaan Basis Data". Ini berarti tidak ada procs, pemicu, dll yang tersimpan - bahkan tidak ada kunci asing.

chris
sumber
8
Apakah ini "independensi" dalam arti bahwa Anda jauh di atas database, Anda lupa data apa? Mengabstraksi database yang tidak perlu "untuk menghindari rasa sakit migrasi" adalah masalah kesayangan; kamu tidak akan membutuhkannya.
Rob
8
Kurang lebih. Astronot arsitektur sedang bekerja. Saya telah membangun aplikasi web sejak ada web, dan selama itu saya tidak pernah pindah dari satu platform db ke platform lain.
chris
5
Saya yakin itu terjadi, tetapi cukup jarang bahwa Anda idiot jika Anda merancang arsitektur di sekitar kemungkinan itu.
chris
6
Harpo, itu situasi yang berbeda - itu persyaratan dalam kasus itu. Saya berbicara tentang ketika itu bukan persyaratan, tetapi AA memutuskan bahwa "mungkin" di beberapa titik.
chris
3
@ Semua: Independensi DB dapat dikenakan biaya, ya, tetapi produk kami dijalankan di lingkungan di mana vendor DB dipilih oleh tawaran, dan kami pada dasarnya harus ikut serta. Beberapa pengembang tidak mendapatkan kemewahan dari tumpukan perangkat lunak yang terintegrasi secara vertikal dan harus melakukan apa pun.
Chris R
31
var stringBuilder = new StringBuilder();
stringBuilder.Append(myObj.a + myObj.b + myObj.c + myObj.d);
string cat = stringBuilder.ToString();

Penggunaan terbaik StringBuilder yang pernah saya lihat.

luft
sumber
9
Bicara tentang "tidak jelas tentang konsep"! Wow!
Eddie
3
Keren. "Pimpinan saya mengatakan saya harus menggunakan kelas StringBuilder jika saya ingin merangkai string. Itulah yang saya lakukan. Jadi apa yang salah?" Lol ...
TheBlastOne
26

Menggunakan regex untuk membagi string ketika string sederhana.split sudah cukup

Cherian
sumber
25
TAPI di Java String.Split menggunakan regex!
Frank Krueger
Saya tidak melihat bagaimana Regex bisa secepat string internal.
Andrei Rînea
2
Tetapi dengan sengaja memburu regex yang digunakan untuk memisahkan string dan menggantinya dengan fungsi split 'sederhana' terdengar seperti contoh pesimisasi yang sempurna. Pustaka regex cukup cepat.
David Crawshaw
5
@ David Crawshaw: Memburu peluang optimasi mikro menghabiskan waktu manusia; bud saat menulis kode, gunakan solusi yang cukup kompleks.
Piskvor meninggalkan gedung
6
-1: Jika Anda terbiasa dengan regex, sangat wajar untuk menulis ini alih-alih membiasakan diri dengan 1001 manipulator string internal-bahasa.
KillianDS
26

Sangat terlambat untuk utas ini saya tahu, tetapi saya melihat ini baru-baru ini:

bool isFinished = GetIsFinished();

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

    case false:
        DoNextStep();
        break;

    default:
        DoNextStep();
}

Kau tahu, kalau-kalau boolean memiliki beberapa nilai tambahan ...

Damovisa
sumber
22
Benar, Salah sebuah FileNotFound ofcourse
Ikke
Hei, Anda harus selalu memiliki default / huruf lain / etc. Apa yang terjadi ketika beberapa orang pintar mengubah boolean menjadi enum untuk mencerminkan status yang lain, lalu orang berikutnya menambah enum dan lupa mengubah prosedur? Memiliki default ketika Anda tidak perlu biaya waktu eksekusi dan sangat sedikit waktu pengembangan. Melacak kesalahan logis yang diperkenalkan secara tidak sengaja yang terjadi selama runtime ... Itu membutuhkan waktu, uang, dan reputasi. Sebuah tusuk waktu menghemat sembilan.
Oorang
1
@Oorang ... mengapa Anda memilikinya sebagai saklar? Ini adalah boolean - if / else adalah semua yang diperlukan.
Damovisa
@Damovisa facepalm benar ... Baiklah kalau begitu :) Rindu itu :)
Oorang
2
Itu adalah Nullable <Boolean> ... :)
George Chakhidze
25

Contoh terburuk yang dapat saya pikirkan adalah basis data internal di perusahaan saya yang berisi informasi tentang semua karyawan. Itu mendapat pembaruan setiap malam dari HR dan memiliki layanan web ASP.NET di atas. Banyak aplikasi lain menggunakan layanan web untuk mengisi hal-hal seperti bidang pencarian / dropdown.

Pesimisme adalah bahwa pengembang berpikir bahwa panggilan berulang ke layanan web akan terlalu lambat untuk membuat kueri SQL berulang. Jadi apa yang dia lakukan? Acara mulai aplikasi membaca di seluruh database dan mengonversikan semuanya menjadi objek dalam memori, disimpan tanpa batas waktu hingga kumpulan aplikasi didaur ulang. Kode ini sangat lambat, butuh 15 menit untuk memuat kurang dari 2000 karyawan. Jika Anda secara tidak sengaja mendaur ulang kumpulan aplikasi pada siang hari, itu bisa memakan waktu 30 menit atau lebih, karena setiap permintaan layanan web akan memulai beberapa pemuatan ulang secara bersamaan. Karena alasan ini, karyawan baru tidak akan muncul di basis data pada hari pertama ketika akun mereka dibuat dan karenanya tidak akan dapat mengakses sebagian besar aplikasi internal pada beberapa hari pertama mereka, memutar-mutar ibu jari mereka.

Pesimisme tingkat kedua adalah bahwa manajer pengembangan tidak ingin menyentuhnya karena takut merusak aplikasi yang bergantung, tetapi kami terus mengalami pemadaman aplikasi kritis di seluruh perusahaan secara sporadis karena buruknya desain komponen sederhana tersebut.

spoulson
sumber
28
Manajemen yang terbaik - "Tidak, jangan luangkan satu kali 80 jam programmer untuk memperbaiki aplikasi ini, itu terlalu mahal. Mari kita simpan saja, sehingga bug-nya dapat menguras 200+ jam pengguna per bulan, ditambah 10 jam programmer per bulan untuk 'pemeliharaan'." AAAAAAAAAUGH !!!
Piskvor meninggalkan gedung
25

Sepertinya tidak ada yang menyebutkan penyortiran, jadi saya akan melakukannya.

Beberapa waktu yang berbeda, saya telah menemukan bahwa seseorang telah membuat kerajinan tangan peleburan, karena situasinya "tidak memerlukan" panggilan ke algoritma quicksort "terlalu mewah" yang sudah ada. Pengembang puas ketika gelembung buatan tangan mereka bekerja cukup baik pada sepuluh baris data yang mereka gunakan untuk pengujian. Itu tidak berjalan dengan baik setelah pelanggan menambahkan beberapa ribu baris.

Dan Breslau
sumber
2
Saya pernah melakukannya sendiri, ketika saya menentukan bahwa biasanya n = 2. Kemudian peningkatan produk membatalkan premis saya, dan kode itu diganti PDQ.
Mark Ransom
2
Ya, tapi itu menyenangkan untuk menulis sesuatu berdasarkan algorythm setiap sekarang;)
UpTheCreek
20

Saya pernah mengerjakan aplikasi yang penuh kode seperti ini:

 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 }

Cukup menghapus found, kembali nulldi akhir, dan mengubah baris keenam menjadi:

            return curr;

Menggandakan kinerja aplikasi.

Dour High Arch
sumber
1
Saya pernah bekerja di sebuah perusahaan di mana pedoman pengkodean menuntut "hanya satu pengembalian di akhir" (untuk pemeliharaan). Dan memang beberapa kode meludahkan seperti milik Anda, karena mereka tidak berpikir (solusi yang jelas adalah sebagian besar waktu menggunakan goto untuk keluar dari proc, atau mengubah kondisi keluar dari loop)
flolo
12
Arus balik di sini menghasilkan perilaku yang sangat berbeda. Saat Anda kembali, Anda akhirnya mendapatkan kecocokan PERTAMA, di mana kode yang Anda tempel mengembalikan kecocokan TERAKHIR.
SoapBox
2
@ SoapBox: Anda Benar. @Lengkungan Tinggi Anda: Peningkatan kinerja tidak ada hubungannya dengan aturan pengembalian tunggal, seperti kata flolo yang mengaitkan kondisi loop ke (curr &&! Found) akan memiliki efek yang sama. GOTO ke pintu keluar proc adalah mengerikan, dan mengalahkan tujuan dari pedoman pengembalian tunggal.
Akusete
2
Komentar yang bagus, semuanya. Dalam hal ini seharusnya hanya ada satu tuple dengan masing-masing ID.
Dour High Arch
7
Tapi itu bukan "Pesimisasi", kan? Ini hanyalah optimisasi yang menunggu untuk terjadi.
Tim Long
20

Saya pernah mencoba mengubah kode yang menyertakan permata ini di kelas Konstanta

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

Masing-masing digunakan beberapa kali di sisa aplikasi untuk tujuan yang berbeda. COMMA_DELIMINATOR mengotori kode dengan lebih dari 200 penggunaan dalam 8 paket berbeda.

KitsuneYMG
sumber
Setidaknya sesuatu seperti itu mudah untuk Menemukan / Mengganti dari sumber - masih, simpati saya.
Erik Forbes
12
Juga - Pembatas? Saya pikir itu dieja 'pembatas'. Deliminator terdengar seperti film pertengahan 90-an yang buruk yang entah bagaimana mendapat 3 sequals ...........
Erik Forbes
53
Deliminator III: Bangkitnya Koma
Rob
33
Pada catatan lain, saya senang melihat pembatasan yang tepat dari Colins. Setiap programmer layak diberi tahu bahwa jika ada satu hal yang harus Anda pisahkan dengan benar, itu adalah Colins.
Rob
2
Tidak mudah melakukan pencarian dan penggantian yang tepat. Karena masing-masing digunakan untuk tujuan yang berbeda. Setiap programmer yang baik setidaknya akan melakukan sesuatu seperti ini: COUNTRY_LIST_DELIM = ...
CLASSIFICATION_DELIM
19

Yang terbesar sepanjang masa, yang saya temukan berulang kali dalam perangkat lunak internal:

Tidak menggunakan fitur-fitur DBMS karena alasan "portabilitas" karena "kami mungkin ingin beralih ke vendor lain nanti".

Baca bibirku. Untuk pekerjaan in-house apa pun: TIDAK AKAN TERJADI!

Peter Stuer
sumber
9
Itu memang terjadi. MySQL -> postgresql, jadi kami tidak kehilangan apa-apa.
Thomas
Atau postgres / postgis -> sqlite / spatialite ... Itu menyebalkan ...
Philip
itu memang terjadi dalam tes JUnit
kachanov
17

Saya memiliki rekan kerja yang mencoba mengecoh optimisator C compiler dan kode penulisan ulang rutin yang hanya bisa dibaca olehnya. Salah satu trik favoritnya adalah mengubah metode yang dapat dibaca seperti (membuat beberapa kode):

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;
}

dalam hal ini:

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

Yaitu, baris pertama dari metode yang pernah dibaca akan menjadi " return" dan semua logika lainnya akan diganti dengan ekspresi terniary yang bersarang. Ketika Anda mencoba untuk berdebat tentang bagaimana hal ini tidak dapat dipelihara, ia akan menunjukkan fakta bahwa output perakitan dari metodenya adalah tiga atau empat instruksi perakitan lebih pendek. Itu tidak selalu lebih cepat tetapi selalu kecil sedikit lebih pendek. Ini adalah sistem tertanam di mana penggunaan memori sesekali penting, tetapi ada optimasi yang jauh lebih mudah yang bisa dibuat daripada ini yang akan membuat kode dapat dibaca.

Kemudian, setelah ini, untuk beberapa alasan dia memutuskan itu ptr->structElement itu terlalu tidak terbaca, jadi dia mulai mengubah semua ini menjadi (*ptr).structElementteori bahwa itu lebih mudah dibaca dan lebih cepat juga.

Mengubah kode yang dapat dibaca menjadi kode yang tidak dapat dibaca untuk paling banyak peningkatan 1%, dan kadang-kadang kode lebih lambat.

Eddie
sumber
Jika modul tersebut disebut jutaan dan jutaan kali per loop, maka saya akan menyetujui optimasi itu selama dia berkomentar sih dari itu.
Michael Dorgan
2
@Michael: Saya tidak akan, kecuali ada pengukuran yang menunjukkan bahwa itu lebih cepat , bukan hanya lebih pendek .
dsimcha
Dalam sebagian besar situasi, operator ternary lebih mudah dibaca daripada if. Desakan pada pernyataan atas ekspresi dalam C adalah dogma budaya / agama, bukan praktik objektif apa pun. (Pedoman yang lebih baik: jika terner bersarang terlalu panjang untuk dibaca, Anda tidak boleh menggunakan ifkeduanya.)
Leushenko
2
Masalahnya di sini adalah mengambil seluruh fungsi dan menggantinya dengan satu pernyataan, pengembalian, sehingga mengganti semua logika dari seluruh fungsi dengan nested ternaries. Jika Anda melihatnya, Anda akan mengerti. Ini bukan hal yang religius "Aku benci operator ternary". Saya tidak berbicara tentang mengambil satu iffungsi dan menggantinya dengan ternary. Itu bagus, dan seringkali lebih mudah dibaca. Saya sedang berbicara tentang mengganti seluruh metode garis 30+ dengan pernyataan kembali tunggal dan terner bersarang. Tidak ada yang mengira kode baru itu lebih mudah dibaca, tetapi satu pengembang berpikir itu lebih cepat.
Eddie
15

Dalam salah satu pekerjaan pertama saya sebagai pengembang penuh, saya mengambil alih proyek untuk sebuah program yang mengalami masalah penskalaan. Ini akan bekerja dengan cukup baik pada set data kecil, tetapi akan benar-benar macet ketika diberikan sejumlah besar data.

Ketika saya menggali, saya menemukan bahwa programmer asli berusaha untuk mempercepat dengan memparalelkan analisis - meluncurkan utas baru untuk setiap sumber data tambahan. Namun, dia membuat kesalahan karena semua utas membutuhkan sumber daya bersama, yang semuanya menemui jalan buntu. Tentu saja, semua manfaat konkurensi menghilang. Selain itu crash sebagian besar sistem untuk meluncurkan 100 utas hanya untuk memiliki semua kecuali satu dari mereka mengunci. Mesin dev berdaging saya adalah pengecualian karena mesin itu mengaduk-aduk 150 sumber data dalam waktu sekitar 6 jam.

Jadi untuk memperbaikinya, saya menghapus komponen multi-threading dan membersihkan I / O. Tanpa perubahan lain, waktu eksekusi pada set data sumber 150 turun di bawah 10 menit pada mesin saya, dan dari tak terbatas hingga di bawah setengah jam pada mesin rata-rata perusahaan.

Jeffrey Blake
sumber
Saya hanya mencegah ini terjadi dalam proyek hari ini. Sekarang saya tahu saya telah membuat pilihan yang baik.
deadalnix
14

Saya kira saya bisa menawarkan permata ini:

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;
}

Karena akar kuadrat dihitung di tempat yang sangat sensitif, saya mendapat tugas mencari cara untuk membuatnya lebih cepat. Refactoring kecil ini mengurangi waktu eksekusi hingga sepertiganya (untuk kombinasi perangkat keras dan kompiler yang digunakan, 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;
}

Tentu saja ada lebih cepat DAN cara yang lebih baik untuk melakukan ini, tapi saya pikir itu adalah contoh pesimisasi yang cukup rapi.

Sunting: Kalau dipikir-pikir, loop terbuka sebenarnya pesimisasi rapi. Menggali melalui kontrol versi, saya dapat menyajikan tahap kedua refactoring juga, yang berkinerja lebih baik daripada yang di atas:

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;
}

Algoritma ini persis sama, walaupun implementasinya sedikit berbeda, jadi saya kira itu memenuhi syarat.

Christoffer
sumber
Saya kira isqrt()menghitung floor(sqrt()), tetapi, mengapa kode ini bekerja?
Pablo H
11

Ini mungkin berada pada tingkat yang lebih tinggi dari apa yang Anda kejar, tetapi memperbaikinya (jika diizinkan) juga melibatkan tingkat rasa sakit yang lebih tinggi:

Bersikeras dengan tangan menggulirkan Object Relationship Manager / Data Access Layer alih-alih menggunakan salah satu perpustakaan yang sudah mapan, teruji, dan sudah ada di luar sana (bahkan setelah ditunjukkan kepada Anda).

Gordon Hartley
sumber
Tidak selalu ide buruk untuk menggulung kode Anda sendiri. Seperti orang bijak yang pernah katakan, temukan ketergantungan dan hilangkan. Jika ini adalah fungsi bisnis inti, lakukan sendiri.
Kibbee
Saya tidak pernah menyimpulkan itu selalu merupakan ide yang buruk. Kecuali Anda mengatakan Frans Bouma atau yang serupa, saya ragu hal-hal ORM / DAL adalah fungsi bisnis inti. Sangat tidak efisien biaya untuk menulis equivelant Anda sendiri, kasus menciptakan kembali roda (persegi), biasanya karena sindrom NIH.
Gordon Hartley
@ Kibbee - Saya setuju. Lebih baik untuk memutar sendiri dan memahaminya daripada menggunakan dependensi pihak ke-3. Ketika rusak (dan itu akan) setidaknya Anda bisa memperbaikinya kemudian. Saya telah menemukan bug di Hibernate dan Apache Commons di masa lalu yang benar-benar mematikan kinerja aplikasi kami.
CodingWithSpike
4
Penggulungan tangan adalah satu-satunya pilihan Anda jika tidak ada yang memiliki fitur penting yang Anda butuhkan.
staticsan
3
Sebenarnya, mengingat beberapa komentar di atas, beberapa perspektif lebih: pesimisasi lain adalah mencoba dan membuat ORM untuk melakukan segalanya. Ini sering berguna untuk lebih dari 95% kasus. Untuk 5% akhir itu, jauh lebih mudah untuk keluar ke kode persistensi buatan tangan / panggilan prosedur tersimpan langsung, dll. Untuk kinerja, kesederhanaan atau keduanya.
Gordon Hartley
10

Semua batasan kunci asing telah dihapus dari database, karena jika tidak, akan ada begitu banyak kesalahan.

Besar
sumber
8

Ini tidak persis sesuai dengan pertanyaan, tetapi saya akan tetap menyebutkannya sebagai kisah peringatan. Saya sedang mengerjakan aplikasi terdistribusi yang berjalan lambat, dan terbang ke DC untuk duduk di sebuah pertemuan yang utamanya ditujukan untuk menyelesaikan masalah. Pimpinan proyek mulai menguraikan arsitektur ulang yang ditujukan untuk menyelesaikan penundaan. Saya mengajukan diri bahwa saya telah melakukan beberapa pengukuran selama akhir pekan yang mengisolasi kemacetan menjadi satu metode. Ternyata ada catatan yang hilang pada pencarian lokal, menyebabkan aplikasi harus pergi ke server jarak jauh pada setiap transaksi. Dengan menambahkan catatan kembali ke toko lokal, penundaan itu dieliminasi - masalah diselesaikan. Perhatikan bahwa arsitektur ulang tidak akan menyelesaikan masalah.

Jack BeNimble
sumber
8

Memeriksa sebelum SETIAP operasi javascript apakah objek yang Anda operasikan ada.

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
}

Masalah saya dengan kode jenis ini adalah tidak ada yang peduli bagaimana jika itu tidak ada? Tidak melakukan apa-apa? Jangan memberikan umpan balik kepada pengguna?

Saya setuju bahwa Object expectedkesalahannya mengganggu, tetapi ini bukan solusi terbaik untuk itu.

Chetan Sastry
sumber
Apa solusi terbaik? Saya pikir itu ceroboh untuk menulis kode, di mana kesalahan sesekali terjadi, bahkan jika mereka tidak memiliki konsekuensi langsung. Tentu saja Anda tidak boleh melakukannya, jika Anda tidak mengharapkan objek menjadi nol dalam keadaan apa pun - mungkin ini yang Anda maksud.
simon
7

Bagaimana dengan ekstremisme YAGNI. Ini adalah bentuk pesimisasi dini. Sepertinya kapan saja Anda menerapkan YAGNI, maka Anda akhirnya membutuhkannya, menghasilkan upaya 10 kali untuk menambahkannya daripada jika Anda telah menambahkannya di awal. Jika Anda membuat program yang berhasil maka kemungkinan besar ANDA AKAN MEMBUTUHKANNYA. Jika Anda terbiasa membuat program yang hidupnya habis dengan cepat maka teruslah berlatih YAGNI karena saya kira YAGNI.

Celup
sumber
3
Terima kasih, saya muak dengan akronim 'pemrograman ekstrem' yang pincang ini dan bagaimana orang menggunakannya untuk mendukung praktik malas dan kontra-produktif.
JAL
Studi tentang proyek aktual menunjukkan bahwa faktor sebenarnya antara rata-rata satu kali dan kode reusbale sekitar 3. Jadi 10 hanyalah nilai "merasa", tetapi Anda benar dengan niat.
peterchen
@ Peterchen - apakah Anda mengatakan bahwa penelitian menunjukkan perlu waktu tiga kali lebih lama untuk menulis kode yang dapat digunakan kembali sebagai kode satu kali, atau mereka menunjukkan bahwa dibutuhkan tiga kali lebih lama untuk mengonversi satu kali kode ke kode yang dapat digunakan kembali daripada untuk menulis kode yang dapat digunakan kembali di tempat pertama?
Jeff Sternal
@ jeff: IIRC mereka membandingkan beberapa ukuran kompleksitas (apa pun yang Anda pikirkan tentang mereka) dari potongan inline yang dipindahkan ke metode terpisah. Kompleksitas meningkat karena tambahan kasus yang didukung, pengecekan parameter dll. (Yang membuat saya berasumsi metodenya agak kecil). Biarkan saya mencoba menggali referensi.
peterchen
6

Bukan optimasi yang terlalu dini - tetapi tentu saja salah arah - ini dibaca di situs BBC, dari sebuah artikel yang membahas Windows 7.

Curran mengatakan bahwa tim Microsoft Windows telah meneliti setiap aspek sistem operasi untuk melakukan perbaikan. "Kami dapat mencukur 400 milidetik dari waktu shutdown dengan sedikit memotong musik shutdown file WAV.

Sekarang, saya belum mencoba Windows 7, jadi saya mungkin salah, tapi saya berani bertaruh bahwa ada masalah lain di sana yang lebih penting daripada berapa lama untuk mematikan. Lagi pula, begitu saya melihat pesan 'Shutting down Windows', monitor dimatikan dan saya berjalan pergi - bagaimana manfaatnya 400 milidetik?

belugabob
sumber
Anda mungkin akan menemukan bahwa masalah lain tidak semudah dijelaskan kepada non-programmer di situs web BBC.
Tom Leys
Nah, itu sudut yang saya tidak menganggap - mungkin aku mulai kehilangan sinisme saya :-)
belugabob
400 ms itu adalah daya tarik 400 ms. Mungkin tidak signifikan, tetapi mungkin bertambah seiring waktu. Tetap saja, bukan sesuatu yang saya khawatirkan.
ZachS
1
Saya telah kehilangan banyak jam total menunggu XP VM untuk ditutup sehingga saya dapat beralih ke hal berikutnya. Saya sangat berterima kasih untuk shutdown yang lebih cepat.
James
1
Menariknya, file WAV diputar secara tidak sinkron, sehingga selama keriuhan shutdown lebih pendek dari waktu yang dibutuhkan untuk shutdown, memotong file WAV tidak menghasilkan apa-apa. Dan yang lebih menarik lagi, jika mereka mengoptimalkan shutdown sangaaaat banyak, kenapa setiap kotak Windows yang saya shutdown membutuhkan waktu lama sampai benar-benar turun? (Kecuali untuk menggunakan tombol merah besar, tentu saja.)
TheBlastOne
6

Seseorang di departemen saya pernah menulis kelas string. Antarmuka sepertiCString , tetapi tanpa ketergantungan Windows.

Satu "optimasi" yang mereka lakukan adalah tidak mengalokasikan lebih banyak memori daripada yang diperlukan. Tampaknya tidak menyadari bahwa alasan mengapa kelas suka std::stringmengalokasikan memori berlebih adalah agar urutan +=operasi dapat berjalan dalam waktu O (n).

Sebagai gantinya, setiap +=panggilan tunggal memaksa realokasi, yang mengubah penambahan berulang menjadi algoritma O (n²) Schlemiel the Painter .

dan04
sumber
5

Seorang mantan rekan kerja tambang (seorang soab , sebenarnya) ditugaskan untuk membangun modul baru untuk Java ERP kami yang seharusnya mengumpulkan dan menganalisis data pelanggan (industri ritel). Dia memutuskan untuk membagi SETIAP bidang Kalender / Datetime dalam komponennya (detik, menit, jam, hari, bulan, tahun, hari dalam seminggu, bimester, trimester (!)) Karena "bagaimana lagi saya akan meminta 'setiap Senin'?"

Joril
sumber
3
Itu bukan optimasi prematur, dia pikir dia perlu melakukan itu untuk kebenaran
Pyrolistic
Tentu, dia pikir dia membutuhkan itu, tetapi karena sebagian besar DBMSes memiliki semacam fungsi DAYOFWEEK (timestamp), melakukan kekacauan di muka itu terlalu dini menurut pendapat saya :)
Joril
1
Saya tidak akan menggunakannya untuk OLTP, tetapi jika Anda "menganalisis data pelanggan" maka itu sebenarnya cara yang sangat fleksibel untuk mendesain data warehouse (selama tanggal dan waktu dibagi menjadi dimensi yang berbeda). Apakah Anda benar-benar ingin memanggil DAYOFWEEK () terhadap jutaan baris data atau hanya melakukan pencarian indeks terhadap bidang bilangan bulat?
Tim Medora
Ya saya tidak tahu apakah ada begitu banyak baris, tetapi tentu saja itu bukan penjelasan yang diberikan :)
Joril
3

Jangan tersinggung siapa pun, tapi saya baru saja menilai tugas (java) yang punya ini

import java.lang.*;
Meluap
sumber
1
Kecuali jika ini adalah kelas tingkat atas, saya pikir Anda perlu mengurangi kelonggaran siswa ini kecuali Anda mengajarinya cukup untuk mengetahui mengapa ini bukan ide yang baik.
Bryan Oakley
24
Apakah saya akan menjadi satu-satunya yang mencatat ironi seorang guru memanggil WTF pada kode seorang siswa bahwa ia bertanggung jawab untuk mengajar program dengan benar?
JohnFx
3
Ya, saya tidak bisa melihat ini akan menyakitkan. Paling buruk itu surpurfluous. Siswa cenderung menggunakan konsistensi yang kaku ketika mereka belajar, dan mengimpor java.lang sangat konsisten dengan apa yang telah dipelajari siswa tentang pengimporan.
cygil
1
Terima kasih semua sudah memberi tahu saya yang jelas. Itu adalah tugas Biologi Komputasi dan saya tidak menghitungnya, atau bahkan menyebutkannya.
Overflown
2
@ JohnFX: Siswa kelas dan guru tidak selalu orang yang sama.
Eddie