Çok sayıda küçük nesnenin yaratılmasını en aza indirmeli misiniz?


10

Sıklıkla çok sayıda (1000) küçük nesne oluşturan bir şey yazarken, bunu performans için en aza indirmeye çalışmalısınız mı? Özellikle hangi sistemde çalışacağını bilmiyorsanız, düşük seviyeli masaüstü bilgisayarlardan hatta mobil cihazlara kadar. Mobil cihazlar için, çok fazla nesne oluşturmanın performansı biraz engellediğini duydum, ancak bunun ne kadar doğru olduğunu bilmiyorum.

Bu fikri iyi gösteren bir örneğim var. Bir grafik programında, ideal olarak adlandırılan tüm çizim için kullanılan bir yöntem olduğunu varsayalım drawPixel(Point). Oluşturulan 1000 puan olabilir ve saniyede 60+ kez çağrılabilecek bir oyunda olduğu gibi sık sık tekrarlanabilir. Alternatif olarak, drawPixel(int x, int y)birçok Point nesnesinin oluşturulmasını en aza indirmek için kullanılabilir.

Nesneye yönelik bir tasarımda bence Point kullanmak tercih edilir. Ancak, ilkel türlerin kullanılması performansı artırabilir. Performans artışı çoğu durumda ihmal edilebilir, ancak mobil veya eski makineler gibi şeylerden emin değilim. Böyle bir şey yapmanın performans kazancı nedir ve dikkate alınması gereken bir şey mi?


Bunu destekleyecek referanslar bulmakta zorlanıyorum, ancak Java 8'de genellikle endişelenmeyin. Açıkçası aptalca şeyler yapmayın, ancak kasten boşa gitmiyorsanız, sistem iyi çalışmalıdır. Sun / Oracle, GC ve bellek yönetimini ayarlamak için yaklaşık 20 yıl geçirdi ve gerçekten çok iyi hale geldi.

@Snowman Java'nın yeni sürümlerinin bellek yönetimi ile daha iyi sonuç verdiğini duydum, ancak gördüğüm sorun, kullanıcının daha eski bir sürümü kullanmadığının garantisi olmadığı. Bu endişemi yaratan şeyin bir parçası.
Stripies

1
Önce biraz performans ölçümü yapın. Bazı sorunlarınız varsa nasıl optimize edeceğinizi düşünün. Ancak, kod performansından çok erken ödün vermeyin, çünkü bazı performans sorunlarınız olabileceğini düşünüyorsunuz .
Benekli

2
@Stripies Daha önce yanıtlanmış olan kısa ömürlü Java nesnelerinin performansı Java'da nesne oluşturulmasını önlemeli miyiz? . Ancak saniyede yüz milyonlarca bu tür nesneyi işlemek zorunda kalırsanız, yalnızca bu noktada bu sorunu yeniden düşünün.
rwong

1
Java'nın eski sürümlerinden endişe ediyorsanız, yüklerken bunu kontrol edin. Bellek yönetimi ile ilgili bir soruna neden olacak kadar eski bir JVM, aynı zamanda birçok iyi bilinen güvenlik sorununa da sahiptir, bu nedenle kullanıcılardan güncelleme istemek onlara bir iyilik yapmaktır. System.getProperty("java.version")(veya "java.vm.version") bir başlangıç ​​noktasıdır.
Jerry Coffin

Yanıtlar:


17

Genel olarak, hayır , performans kaybı korkusu için nesneler oluşturmaktan kaçınmamalısınız. Bunun birkaç nedeni var.

  1. Nesneleri kullanmak, Java'yı kullanmanın bir noktasıdır. Onları önleyici olarak kullanmak, Java'yı kullanma kararının başlangıçta doğru olmayabileceğinin bir işaretidir.
  2. Performans sorunları vardır herkesin bildiği tahmin etmek zor. Asla bir şeyin bir darboğaz olduğunu varsaymayın. Daima ölçün. Performans mühendisliği neredeyse her zaman tam olarak doğru yerde küçük değişiklikler yapmakla ilgilidir. Bir ilacın etkisini deney yapmadan tahmin edebileceğinizden daha fazla ölçmeden doğru yeri tahmin edemezsiniz.
  3. Nesne oluşturma maliyeti çok fazla tahmin edilmektedir. Modern bir JVM'de temel olarak bir işaretçiyi arttırmak anlamına gelir (ve kuşak çöp toplayıcıları ile, yönetim maliyeti de önemsizdir). İnternette nesnelerden kaçınmanızı, nesne havuzlamayı vb. Kullanmanızı tavsiye eden birçok metin vardır. Bu tavsiye bazen 1990'larda doğrudur; bugün çoğunlukla modası geçmiş. Nesnelerden kaçınarak veya bunları kendiniz yöneterek getirilen ek geliştirme maliyetini ve karmaşıklığını haklı çıkarmak için yeterli performans kazanmanız pek olası değildir.

Bununla birlikte, bir nesneye bir şey yapmanın başlangıçta mantıklı olmadığı yerler vardır. Bir çizim rutinine iki koordinat geçirmek böyle bir durum olabilir: koordinat çiftinin bağımsız bir varlığı yoktur, kimliği yoktur, sadece bir kez kullanılır ve hemen atılır, vb.

Bu durumda, emin olun, devam edin ve intbir nesneye sarmak yerine iki s geçirin. OOP'un amacı, her şeyin bir nesne olması gerektiği değildir. Mesele şu ki, bir veri temsil probleminin doğal çözümü oldukları yerlerde nesneler gelişimi kolaylaştırmaktadır. Mantıklı oldukları nesnelerden kaçının - onlara olmayanları tanıtmayın.


2

Kod yazmadan önce performans üzerindeki etkileri düşünürken ne yaptığınızı bilmediğinizi varsaymalısınız.

Java'da ilkellere karşı nesneler için çok küçük bir alan yükü vardır. Nesneleriniz ne kadar küçük olursa, ek yükün yüzdesi o kadar büyük olur. Ancak, uzun zaman önce n'yi n ile n ile çarpan şeylere nazaran çift n şeylerin bir şey olmadığını öğrendim.

Bu yüzden evet, yarısı büyüklüğünde bir etki yaratan veya hatta dörtte biri olan bir sistemi taklit edebilirsiniz, lütfen neden gerçekten önemsediğinizi kendinize sorun. Bu soruna karmaşık çözümler iyi karşılanmayacaktır. Özellikle böyle bir koda dalış yapmak kafa karıştırıcı olacaktır. Karışık programcılar kötü kod yazarlar. N log n kodu olması gereken n kere n kodu yazarlar. Ve bunu yapmak daha uzun sürüyor.

Şimdi, bana konuşabileceğimiz çoğu zaman içine bakmak zorunda olmadığım güzel bir kutuya uyan bir numara ile yer kazanabilirsen. Bu kutu daha iyi çalıştığında başka bir kutu için takas edebilirim, bunun için bile ödeme yapabilirim.


2

Yaptığım performans ayarlamasında ( örnek ) bellek yönetiminin büyük bir suçlu olması çok kolaydır. Yeni operatörü ve çöp toplayıcıyı ne kadar çılgınca ayarladıklarını umursamıyorum , en hızlı hesaplama hesaplama değildir. Bellek yöneticisinin çok fazla zaman aldığını görürsem ve nesne yapmaktan kaçınamıyorsam , sürekli yenilerini yapmak yerine onları yeniden kullanmanın bir yolunu bulurum.

Bunu sadece nesne yapmak zorunda olduğum zaman yapıyorum. Grafikler için genellikle yapmam. IMHO, grafikler çizilmeli , inşa edilmemelidir . Elbette, bir resmin noktalar, onları birbirine bağlayan çizgiler, çokgenler, metin vb. Yani alternatifi anlamına gelmez yapım nesneleri daha önce onlardan çizmek onları. Sadece çiziyorum.

Bir Paint yöntemi var. Bunu geçersiz kıldım, her şeyi bir bitmap'e çiziyorum ve sonra ekrana aktarmayı engelliyorum. Anlık görünüyor. Fare girişi için, geçersiz kılma, tıklamayı, sürüklemeyi, ne olursa olsun algılamak için yöntemler vardır.

OOP belirli nedenlerle iyi bir fikirdir. Bu nedenler her durumda geçerli değildir .


Katılıyorum, ama aynı zamanda herkesle test etmenin kesin olarak bilmenin tek yolu olduğunu da kabul ediyorum. Optimize etmeden önce teknik özellikleri basit / açık bir şekilde yaptığınızdan emin olun ... ancak yeninin hala bir sorun olabileceğini kabul ediyorum.
Bill K

2

Devam edin ve küçük tahsisler kullanın. Modern bellek yöneticileri, özellikle yüksek düzeyde optimize edilmiş Java nesne yöneticisi, son derece verimlidir. Çalışan bir program için büyük performans optimizasyonunu kaydedin.

Genel performansın yeterli olması son derece olasıdır. Durum böyle değilse, o zaman ve ancak o zaman , kodun performansını profilleyin. Uzun bir yazılım geliştirme kariyerinde, darboğazların neredeyse hiç beklediğiniz yerde olmadığını öğrendim.

Bir zamanlar bir ekip üyesinin nesne gününü 20 kat daha hızlı aramasını sağlamak için birkaç gün geçirmiştim. Başarı! Bununla birlikte, fiili kullanımda en iyi toplam hızlanma, yüzde yüzde biriyle ölçülmüştür. Değişiklik hemen geri çekildi, çünkü hızlandırma her üye bellek tahsisi için daha büyük gerektiriyordu.


1

Çok basit: 1000 küçük nesneye ihtiyacınız varsa, 1000 küçük nesne oluşturursunuz ve bunun için endişelenmeyin. 100 küçük nesneye ihtiyacınız varsa , 1000 küçük nesne oluşturmak aptalca olur - ihtiyacınız olanları oluşturun, daha fazlasını değil.

Performans konusunda endişeleniyorsanız (ve performans konusunda da endişelenmiyorsanız) , tek bir yerde bir kez yazılan herhangi bir işlevselliğe sahip olmalısınız , bu da tüm kodunuzu daha basit ve anlaşılmasını kolaylaştırır. Sonra eğer bir performans sorun var, o zaman orada olduğunu size gösterebilir ölçme tek performans sorunu kolaylık sağlayacak, olur yeri ve bunu değiştirmek için gereken tek bir yer. Veya ölçüm, bu yerin herhangi bir soruna neden olmadığını gösterir, bu yüzden işiniz bitti.

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.