Pertanyaan saya berkaitan dengan karakteristik kinerja metode statis vs metode contoh dan skalabilitasnya. Asumsikan untuk skenario ini bahwa semua definisi kelas berada dalam satu rakitan dan beberapa jenis penunjuk diskrit diperlukan.
Mempertimbangkan:
public sealed class InstanceClass
{
public int DoOperation1(string input)
{
// Some operation.
}
public int DoOperation2(string input)
{
// Some operation.
}
// … more instance methods.
}
public static class StaticClass
{
public static int DoOperation1(string input)
{
// Some operation.
}
public static int DoOperation2(string input)
{
// Some operation.
}
// … more static methods.
}
Kelas-kelas di atas mewakili pola gaya helper.
Dalam kelas instance, menyelesaikan metode instance membutuhkan waktu beberapa saat untuk dilakukan sebagai lawan dari StaticClass.
Pertanyaan saya adalah:
Saat mempertahankan status tidak menjadi perhatian (tidak ada bidang atau properti yang diperlukan), apakah selalu lebih baik menggunakan kelas statis?
Di mana terdapat sejumlah besar definisi kelas statis ini (misalnya 100, dengan sejumlah metode statis masing-masing) akankah hal ini mempengaruhi kinerja eksekusi atau konsumsi memori secara negatif dibandingkan dengan jumlah definisi kelas instance yang sama?
Ketika metode lain dalam kelas instance yang sama dipanggil, apakah resolusi instance masih terjadi? Misalnya menggunakan kata kunci [ini] seperti
this.DoOperation2("abc")
dari dalamDoOperation1
contoh yang sama.
sumber
this
menunjuk ke sesuatu ketika kelas memanggil metode instance pada dirinya sendiri?"Jawaban:
Secara teori, metode statis harus bekerja sedikit lebih baik daripada metode instance, semua hal lain dianggap sama, karena
this
parameter tersembunyi ekstra .Dalam praktiknya, ini hanya membuat sedikit perbedaan sehingga akan tersembunyi dalam kebisingan berbagai keputusan compiler. (Oleh karena itu, dua orang dapat "membuktikan" yang satu lebih baik daripada yang lain dengan hasil yang tidak setuju). Paling tidak karena
this
biasanya diteruskan dalam register dan sering kali dalam register itu untuk memulai.Poin terakhir ini berarti bahwa dalam teori, kita harus mengharapkan metode statis yang mengambil objek sebagai parameter dan melakukan sesuatu dengannya menjadi sedikit kurang baik daripada yang setara sebagai instance pada objek yang sama. Sekali lagi, perbedaannya sangat kecil sehingga jika Anda mencoba mengukurnya, Anda mungkin akan mengukur beberapa keputusan compiler lainnya. (Terutama karena kemungkinan jika referensi itu berada dalam register sepanjang waktu juga cukup tinggi).
Perbedaan kinerja sebenarnya akan turun ke apakah Anda memiliki objek secara artifisial dalam memori untuk melakukan sesuatu yang seharusnya statis, atau Anda menjerat rantai pengoperan objek dengan cara yang rumit untuk melakukan apa yang seharusnya secara alami menjadi contoh.
Oleh karena itu untuk nomor 1. Ketika menjaga status bukanlah masalah, selalu lebih baik untuk menjadi statis, karena untuk itulah statis . Ini bukan masalah kinerja, meskipun ada aturan keseluruhan untuk bermain baik dengan pengoptimalan kompiler - kemungkinan besar seseorang berusaha mengoptimalkan kasus yang muncul dengan penggunaan normal daripada kasus yang muncul dengan penggunaan aneh.
Nomor 2. Tidak ada bedanya. Ada sejumlah biaya per kelas untuk setiap anggota, baik dari segi berapa banyak metadata yang ada, berapa banyak kode yang ada dalam file DLL atau EXE yang sebenarnya, dan berapa banyak kode jitted yang ada. Ini sama apakah itu instance atau statis.
Dengan item 3,
this
sepertithis
halnya. Namun perhatikan:The
this
parameter dilewatkan di register tertentu. Saat memanggil metode instance dalam kelas yang sama, kemungkinan besar sudah ada di register itu (kecuali jika disimpan dan register digunakan untuk beberapa alasan) dan karenanya tidak ada tindakan yang diperlukan untuk menyetelthis
ke apa yang perlu disetel ke . Ini berlaku sampai batas tertentu misalnya, dua parameter pertama pada metode menjadi dua parameter pertama dari panggilan yang dibuatnya.Karena akan jelas bahwa
this
ini bukan null, ini dapat digunakan untuk mengoptimalkan panggilan dalam beberapa kasus.Karena akan jelas bahwa
this
itu bukan null, ini dapat membuat pemanggilan metode sebaris lebih efisien lagi, karena kode yang dihasilkan untuk memalsukan pemanggilan metode dapat menghilangkan beberapa pemeriksaan nol yang mungkin diperlukan.Konon, cek nol itu murah!
Perlu dicatat bahwa metode statis generik yang bekerja pada suatu objek, daripada metode instan, dapat mengurangi beberapa biaya yang dibahas di http://joeduffyblog.com/2011/10/23/on-generics-and-some-of- overhead-terkait / dalam kasus di mana statis yang diberikan tidak dipanggil untuk jenis tertentu. Seperti yang dia katakan, "Sebagai tambahan, ternyata metode penyuluhan adalah cara yang bagus untuk membuat abstraksi umum lebih menguntungkan."
Namun, perhatikan bahwa ini hanya berkaitan dengan instansiasi tipe lain yang digunakan oleh metode, yang sebaliknya tidak ada. Dengan demikian, ini benar-benar tidak berlaku untuk banyak kasus (beberapa metode contoh lain menggunakan tipe itu, beberapa kode lain di tempat lain menggunakan tipe itu).
Ringkasan:
Sunting: Sebuah catatan tentang betapa murahnya cek-nol (yang saya klaim di atas). Kebanyakan pemeriksaan-nol di .NET tidak memeriksa nol sama sekali, melainkan mereka melanjutkan apa yang akan mereka lakukan dengan asumsi bahwa itu akan berhasil, dan jika pengecualian akses terjadi, itu akan berubah menjadi
NullReferenceException
. Dengan demikian, sebagian besar ketika secara konseptual kode C # melibatkan pemeriksaan null karena mengakses anggota instance, biaya jika berhasil sebenarnya nol. Pengecualiannya adalah beberapa panggilan inline, (karena mereka ingin berperilaku seolah-olah mereka memanggil anggota instance) dan mereka baru saja menekan sebuah bidang untuk memicu perilaku yang sama, jadi panggilan tersebut juga sangat murah, dan mereka masih sering ditinggalkan (misalnya jika langkah pertama dalam metode tersebut melibatkan mengakses bidang sebagaimana adanya).sumber
this
atau melalui parameter eksplisit. Dampak yang lebih besar di sini adalah seberapa dekat data dengan data terkait (bidang tipe nilai atau nilai larik lebih dekat daripada data di bidang tipe referensi) dan pola akses.obj.DoSomehting(2)
akan sedikit lebih murah daripadaDoSomething(obj, 2)
tetapi karena saya juga mengatakan perbedaannya sangat kecil dan sangat bergantung pada hal-hal kecil yang mungkin berakhir berbeda dalam kompilasi akhir sehingga tidak perlu dikhawatirkan sama sekali. Jika Anda melakukan sesuatu yang mahal (relatif terhadap jenis perbedaan dalam permainan di sini) seperti menserialisasikan sesuatu ke string maka itu sangat tidak berguna.ctor
masih membutuhkan inisialisasi semua field. Setelah Anda memiliki sebuah contoh, jawaban ini berlaku ("semua hal lain dianggap sama"). Tentu saja, biaya yang mahal jugacctor
dapat membuat metode statis menjadi lambat, tetapi itu hanya pada panggilan pertama yang berlaku untuk metode instance secara setara. Lihat juga docs.microsoft.com/en-us/previous-versions/dotnet/articles/…Saya akan menjawab, ya. Saat mendeklarasikan sesuatu,
static
Anda mendeklarasikan maksud dari eksekusi tanpa kewarganegaraan (ini tidak wajib, tetapi maksud dari sesuatu yang diharapkan)Jangan berpikir demikian, kecuali Anda yakin bahwa kelas statis benar - benar tidak stabil, karena jika tidak, akan mudah mengacaukan alokasi memori dan mendapatkan kebocoran memori.
Tidak yakin, tentang hal ini (ini adalah detail implementasi CLR murni), tapi pikirkan ya.
sumber
metode statis lebih cepat tetapi kurang OOP, jika Anda akan menggunakan pola desain metode statis kemungkinan kode buruk, untuk menulis logika bisnis lebih baik tanpa statis, fungsi umum seperti membaca file, WebRequest dll lebih baik disadari sebagai statis ... Anda pertanyaan tidak memiliki universal menjawab
sumber