Haruskah Anda meminimalkan penciptaan banyak benda kecil?

10

Saat menulis sesuatu yang sering membuat (1000-an) benda kecil, haruskah Anda mencoba meminimalkannya untuk kinerja? Terutama jika Anda tidak tahu sistem apa yang akan dijalankan, dari desktop rendah ke tinggi atau bahkan ponsel. Untuk seluler, saya mendengar bahwa membuat banyak objek sedikit menghalangi kinerja, meskipun saya tidak tahu seberapa benar itu.

Saya punya contoh yang menunjukkan ide ini dengan baik. Dalam program grafis, katakan ada metode yang digunakan untuk semua gambar yang disebut ideal drawPixel(Point). Mungkin ada 1000 Poin yang dibuat dan itu bisa diulang sering, seperti dalam game di mana itu bisa disebut 60+ kali per detik. Atau, drawPixel(int x, int y)dapat digunakan untuk meminimalkan penciptaan banyak objek Point.

Dalam desain berorientasi objek, saya pikir menggunakan Point akan lebih disukai. Namun, menggunakan tipe primitif dapat meningkatkan kinerja. Peningkatan kinerja mungkin diabaikan dalam banyak kasus, tapi saya tidak yakin tentang hal-hal seperti ponsel atau mesin yang lebih tua. Apa keuntungan kinerja dari melakukan sesuatu seperti ini dan apakah itu sesuatu yang harus dipertimbangkan?

Stripies
sumber
Saya mengalami kesulitan menemukan referensi untuk mendukung ini, tetapi secara umum di Java 8 jangan khawatir tentang hal itu. Jangan melakukan hal-hal yang jelas-jelas bodoh, tetapi jika Anda tidak sengaja boros sistemnya akan baik-baik saja. Sun / Oracle telah memiliki sekitar 20 tahun untuk menyempurnakan GC dan manajemen memori dan mereka menjadi sangat baik.
@Snowman Saya telah mendengar bahwa versi Java yang lebih baru lebih baik dengan manajemen memori, tetapi masalah yang saya lihat adalah tidak ada jaminan pengguna tidak menggunakan versi yang lebih lama. Itu bagian dari apa yang menciptakan kekhawatiran saya ini.
Stripies
1
Pertama lakukan beberapa pengukuran kinerja. Jika Anda memiliki beberapa masalah, pikirkan cara mengoptimalkan. Tapi tolong jangan mengorbankan pemeliharaan kode terlalu dini karena Anda pikir Anda dapat memiliki beberapa masalah kinerja.
Terlihat
2
@ Trips Kinerja objek Java yang berumur pendek sudah dijawab dalam Haruskah kita menghindari pembuatan objek di Jawa? . Namun, jika Anda harus menangani ratusan juta objek seperti itu per detik, maka hanya pada saat itu pertimbangkan masalah ini.
rwong
1
Jika Anda khawatir tentang versi Java yang lebih lama, periksa ketika Anda menginstal. JVM yang cukup tua untuk menyebabkan masalah dengan manajemen memori, juga memiliki banyak masalah keamanan yang terkenal juga, sehingga mendorong pengguna untuk memperbarui adalah membantu mereka. System.getProperty("java.version")(atau "java.vm.version") adalah titik awal.
Jerry Coffin

Jawaban:

17

Secara umum, tidak , Anda tidak harus menghindari membuat objek karena takut kehilangan kinerja. Ada beberapa alasan untuk ini.

  1. Menggunakan objek adalah semacam titik menggunakan Java. Menghindari mereka terlebih dahulu adalah tanda bahwa keputusan untuk menggunakan Java mungkin bukan keputusan yang tepat untuk memulai.
  2. Masalah kinerja sangat sulit diprediksi. Jangan pernah berasumsi bahwa sesuatu adalah hambatan. Selalu ukur. Rekayasa kinerja hampir selalu merupakan masalah membuat perubahan kecil di tempat yang tepat. Anda tidak dapat memprediksi tempat yang tepat tanpa mengukur lebih dari yang Anda dapat memprediksi efek obat tanpa percobaan.
  3. Biaya pembuatan objek sangat ditaksir. Dalam JVM modern, ini pada dasarnya sama dengan menambah pointer (dan dengan pengumpul sampah generasi, biaya pengelolaannya juga sepele). Ada banyak teks di internet yang menyarankan Anda untuk menghindari objek, menggunakan pengumpulan objek dll. Saran ini kadang-kadang tepat di tahun 1990-an; hari ini sebagian besar sudah usang. Anda sangat tidak mungkin mendapatkan kinerja yang cukup untuk membenarkan biaya pengembangan tambahan dan kompleksitas yang diperkenalkan dengan menghindari Obyek atau mengelolanya sendiri.

Yang mengatakan, ada tempat di mana membuat sesuatu menjadi objek tidak masuk akal untuk memulai. Melewati dua koordinat ke rutinitas menggambar bisa menjadi kasus seperti itu: pasangan koordinat tidak memiliki keberadaan independen, tidak memiliki identitas, digunakan hanya sekali dan kemudian segera dibuang, dll.

Jika ini masalahnya, maka tentu saja, lanjutkan dan lewati dua ints daripada membungkusnya menjadi objek. Maksud OOP bukanlah bahwa segala sesuatu harus menjadi objek. Intinya adalah bahwa objek membuat pengembangan lebih mudah di tempat-tempat di mana mereka adalah solusi alami untuk masalah representasi data. Jangan menghindari benda-benda yang masuk akal - jangan memperkenalkannya di tempat yang tidak masuk akal.

Kilian Foth
sumber
2

Ketika merenungkan dampak pada kinerja sebelum Anda menulis kode, Anda harus menganggap Anda tidak tahu apa yang Anda lakukan.

Ada overhead ruang yang sangat kecil untuk objek di java versus primitif. Semakin kecil objek Anda, semakin besar persentase overhead. Namun, saya telah lama belajar bahwa hal-hal yang menggandakan n tidak ada apa-apanya dibandingkan dengan hal-hal yang berlipat ganda n

Jadi sementara ya Anda dapat memperdayai beberapa sistem yang memiliki dampak ukuran setengah atau bahkan keempat, tanyakan pada diri sendiri mengapa Anda benar-benar peduli. Solusi rumit untuk masalah ini tidak akan diterima dengan baik. Terutama karena menyelam ke kode semacam itu akan membingungkan. Programmer yang bingung menulis kode yang buruk. Mereka menulis n kali n kode yang seharusnya n log n kode. Dan mereka membutuhkan waktu lebih lama untuk melakukannya.

Sekarang jika Anda dapat menghemat ruang saya dengan beberapa trik yang cocok dalam kotak yang bagus yang saya tidak perlu melihat ke dalam sebagian besar waktu kita dapat berbicara. Jika kotak saya bisa menukar dengan kotak lain ketika kotak itu bekerja lebih baik, saya bahkan mungkin membayar untuk itu.

candied_orange
sumber
2

Dalam penyetelan kinerja yang telah saya lakukan ( contoh ), sangat mudah bagi manajemen memori untuk menjadi penyebab utama. Saya tidak peduli seberapa gilanya mereka mengatur operator baru dan pengumpul sampah, perhitungan tercepat bukanlah penghitungan. Jadi jika saya menemukan manajer memori membutuhkan waktu yang lama, dan saya tidak bisa menghindari membuat objek , maka saya menemukan cara untuk menggunakannya kembali, daripada terus-menerus membuat yang baru.

Saya hanya melakukan ini jika saya harus membuat objek. Untuk grafis, biasanya saya tidak. IMHO, gambar harus dibuat , bukan dibangun . Tentu, Anda bisa mengatakan bahwa gambar terdiri dari titik, garis yang menghubungkannya, poligon, teks, dan sebagainya. Itu tidak berarti Anda tidak memiliki alternatif untuk membuat benda-benda sebelum Anda menggambarnya . Saya hanya menggambar mereka.

Ada metode Paint. Saya menimpanya, menggambar semuanya menjadi bitmap, dan kemudian memblokir transfernya ke layar. Itu terlihat seketika. Untuk input mouse, ada metode untuk mengganti, untuk mendeteksi mengklik, menyeret, apa pun.

OOP adalah ide bagus untuk alasan tertentu. Alasan itu tidak berlaku dalam semua situasi.

Mike Dunlavey
sumber
Saya setuju, tetapi saya juga setuju dengan semua orang bahwa pengujian adalah satu-satunya cara untuk mengetahui dengan pasti. Pastikan Anda memiliki spesifikasi melakukannya dengan cara yang sederhana / jelas sebelum mengoptimalkannya ... tapi saya setuju bahwa baru masih bisa menjadi masalah.
Bill K
2

Silakan dan gunakan alokasi kecil. Manajer memori modern, khususnya manajer objek Java yang sangat dioptimalkan, sangat efisien. Simpan optimasi kinerja utama untuk program kerja.

Sangat mungkin bahwa kinerja keseluruhan akan memadai. Jika ternyata bukan itu masalahnya, maka, dan baru setelah itu , profil kinerja kodenya. Dalam karir panjang pengembangan perangkat lunak, saya telah belajar bahwa kemacetan hampir tidak pernah seperti yang Anda harapkan.

Saya pernah meminta seorang anggota tim menghabiskan beberapa hari membuat pencarian anggota objek 20x lebih cepat. Keberhasilan! Namun, speedup keseluruhan terbaik dalam penggunaan aktual diukur dalam seratus persen. Perubahan segera dibatalkan, karena speedup membutuhkan alokasi memori yang lebih besar per anggota.

Bill Ferguson
sumber
1

Sederhana: Jika Anda membutuhkan 1000 objek kecil, maka Anda membuat 1000 objek kecil dan tidak perlu khawatir. Jika Anda membutuhkan 100 objek kecil, maka membuat 1000 objek kecil itu bodoh - buat yang Anda butuhkan dan tidak lebih.

Jika Anda khawatir tentang kinerja (dan jika Anda tidak khawatir tentang kinerja juga), Anda harus memiliki fungsionalitas yang ditulis sekali di satu tempat, yang membuat seluruh kode Anda lebih sederhana dan lebih mudah dipahami. Kemudian jika Anda memiliki masalah kinerja, maka pengukuran dapat menunjukkan kepada Anda bahwa ada satu tempat di mana masalah kinerja terjadi, yang membuat segalanya lebih mudah, dan hanya satu tempat di mana Anda perlu mengubahnya. Atau pengukuran menunjukkan bahwa tempat ini tidak menimbulkan masalah, jadi Anda sudah selesai.

gnasher729
sumber