Saya menggunakan Log4J dalam aplikasi saya untuk login. Sebelumnya saya menggunakan panggilan debug seperti:
Pilihan 1:
logger.debug("some debug text");
tetapi beberapa tautan menyarankan bahwa lebih baik untuk memeriksa isDebugEnabled()
dulu, seperti:
Pilihan 2:
boolean debugEnabled = logger.isDebugEnabled();
if (debugEnabled) {
logger.debug("some debug text");
}
Jadi pertanyaan saya adalah " Apakah opsi 2 meningkatkan kinerja? ".
Karena bagaimanapun kerangka Log4J memiliki pemeriksaan yang sama untuk debugEnabled. Untuk opsi 2 mungkin bermanfaat jika kita menggunakan beberapa pernyataan debug dalam metode atau kelas tunggal, di mana kerangka kerja tidak perlu memanggil isDebugEnabled()
metode beberapa kali (pada setiap panggilan); dalam hal ini ia memanggil isDebugEnabled()
metode hanya sekali, dan jika Log4J dikonfigurasi ke level debug maka sebenarnya ia memanggil isDebugEnabled()
metode dua kali:
- Dalam hal memberikan nilai ke variabel debugEnabled, dan
- Sebenarnya disebut dengan metode logger.debug ().
Saya tidak berpikir bahwa jika kita menulis beberapa logger.debug()
pernyataan dalam metode atau kelas dan memanggil debug()
metode menurut opsi 1 maka itu adalah overhead untuk kerangka kerja Log4J dibandingkan dengan opsi 2. Karena isDebugEnabled()
merupakan metode yang sangat kecil (dalam hal kode), mungkin menjadi kandidat yang baik untuk inlining.
toString()
hanya jika diperlukan.Karena dalam opsi 1 string pesan adalah konstan, sama sekali tidak ada keuntungan dalam membungkus pernyataan logging dengan suatu kondisi, sebaliknya, jika pernyataan log diaktifkan debug, Anda akan mengevaluasi dua kali, sekali dalam
isDebugEnabled()
metode dan sekali dalamdebug()
metode. Biaya memohonisDebugEnabled()
dalam urutan 5 hingga 30 nanodetik yang harus diabaikan untuk tujuan paling praktis. Dengan demikian, opsi 2 tidak diinginkan karena mencemari kode Anda dan tidak memberikan keuntungan lainnya.sumber
Menggunakan tanda
isDebugEnabled()
disediakan untuk ketika Anda membangun pesan log dengan merangkai Strings:Namun, dalam contoh Anda tidak ada peningkatan kecepatan karena Anda hanya mencatat String dan tidak melakukan operasi seperti penggabungan. Karena itu Anda hanya menambahkan mengasapi kode Anda dan membuatnya lebih sulit untuk dibaca.
Saya pribadi menggunakan panggilan format Java 1.5 di kelas String seperti ini:
Saya ragu ada banyak optimasi tetapi lebih mudah dibaca.
Harap perhatikan bahwa sebagian besar API logging menawarkan format seperti ini di luar kotak: slf4j misalnya menyediakan yang berikut ini:
yang bahkan lebih mudah dibaca.
sumber
Di Java 8, Anda tidak harus menggunakan
isDebugEnabled()
untuk meningkatkan kinerja.https://logging.apache.org/log4j/2.0/manual/api.html#Java_8_lambda_support_for_lazy_logging
sumber
Versi Pendek: Anda mungkin juga melakukan pemeriksaan boolean isDebugEnabled ().
Alasan:
1- Jika logika / string string rumit. ditambahkan ke pernyataan debug Anda, Anda sudah memiliki tanda centang di tempat.
2- Anda tidak harus secara selektif memasukkan pernyataan tentang pernyataan debug "kompleks". Semua pernyataan dimasukkan seperti itu.
3- Memanggil log.debug menjalankan perintah berikut sebelum masuk:
if(repository.isDisabled(Level.DEBUG_INT))
return;
Ini pada dasarnya sama dengan log panggilan. atau kucing. isDebugEnabled ().
NAMUN! Inilah yang dipikirkan oleh para pengembang log4j (seperti di javadoc mereka dan Anda mungkin harus melakukannya).
Inilah metodenya
Ini javadoc untuk itu
sumber
Seperti yang disebutkan orang lain menggunakan pernyataan penjaga hanya benar-benar berguna jika membuat string adalah panggilan yang memakan waktu. Contoh spesifik dari ini adalah ketika membuat string akan memicu beberapa pemuatan malas.
Perlu dicatat bahwa masalah ini dapat diselesaikan dengan menggunakan Facade Logging Sederhana untuk Java atau (SLF4J) - http://www.slf4j.org/manual.html . Ini memungkinkan pemanggilan metode seperti:
Ini hanya akan mengkonversi parameter yang diteruskan ke string jika debug diaktifkan. SLF4J seperti namanya hanya fasad dan panggilan logging dapat diteruskan ke log4j.
Anda juga dapat dengan mudah "memutar versi Anda sendiri" dari ini.
Semoga ini membantu.
sumber
Opsi 2 lebih baik.
Per se itu tidak meningkatkan kinerja. Tapi itu memastikan kinerja tidak menurun. Begini caranya.
Biasanya kami mengharapkan logger.debug (someString);
Tetapi biasanya, seiring pertumbuhan aplikasi, banyak perubahan, terutama pengembang pemula, Anda dapat melihatnya
logger.debug (str1 + str2 + str3 + str4);
dan sejenisnya.
Bahkan jika level log diatur ke KESALAHAN atau FATAL, rangkaian string dapat terjadi! Jika aplikasi ini berisi banyak pesan tingkat DEBUG dengan rangkaian string, maka tentu dibutuhkan kinerja yang luar biasa terutama dengan jdk 1.4 atau lebih rendah. (Saya tidak yakin apakah nanti versi jdk internall melakukan stringbuffer.append ()).
Itu sebabnya Opsi 2 aman. Bahkan penggabungan string tidak terjadi.
sumber
Seperti @erickson, itu tergantung. Jika saya ingat,
isDebugEnabled
sudah membangundebug()
metode Log4j.Selama Anda tidak melakukan beberapa perhitungan mahal dalam pernyataan debug Anda, seperti loop pada objek, melakukan perhitungan dan merangkai string, Anda baik-baik saja menurut saya.
akan lebih baik
sumber
Untuk satu baris , saya menggunakan bagian dalam pesan logging, dengan cara ini saya tidak melakukan penggabungan:
ej:
Saya lakukan:
Tetapi untuk beberapa baris kode
ej.
Saya lakukan:
sumber
Karena banyak orang mungkin melihat jawaban ini ketika mencari log4j2 dan hampir semua jawaban saat ini tidak mempertimbangkan log4j2 atau perubahan terbaru di dalamnya, semoga ini akan menjawab pertanyaan.
log4j2 mendukung Pemasok (saat ini implementasi mereka sendiri, tetapi menurut dokumentasi direncanakan untuk menggunakan antarmuka Pemasok Java dalam versi 3.0). Anda dapat membaca sedikit lebih banyak tentang ini di manual . Ini memungkinkan Anda untuk memasukkan pembuatan pesan log yang mahal ke pemasok yang hanya membuat pesan jika akan dicatat:
sumber
Ini meningkatkan kecepatan karena itu umum untuk merangkai string dalam teks debug yang mahal misalnya:
sumber
Karena versi Log4j
2.4
(atauslf4j-api 2.0.0-alpha1
) jauh lebih baik menggunakan API yang lancar (atau dukungan Java 8 lambda untuk lazy logging ), yang mendukungSupplier<?>
argumen pesan log, yang dapat diberikan oleh lambda :ATAU dengan slf4j API:
sumber
Jika Anda menggunakan opsi 2 Anda melakukan pemeriksaan Boolean yang cepat. Dalam opsi yang Anda lakukan pemanggilan metode (mendorong barang-barang di tumpukan) dan kemudian melakukan pemeriksaan Boolean yang masih cepat. Masalah yang saya lihat adalah konsistensi. Jika beberapa pernyataan debug dan info Anda dibungkus dan beberapa tidak, itu bukan gaya kode yang konsisten. Plus seseorang nanti dapat mengubah pernyataan debug untuk memasukkan string gabungan, yang masih cukup cepat. Saya menemukan bahwa ketika kami menyelesaikan pernyataan debug dan info dalam aplikasi besar dan memprofilkannya, kami menyimpan beberapa poin persentase dalam kinerja. Tidak banyak, tetapi cukup untuk membuatnya sepadan dengan pekerjaan. Saya sekarang memiliki beberapa pengaturan makro di IntelliJ untuk secara otomatis menghasilkan debug debug dan pernyataan info untuk saya.
sumber
Saya akan merekomendasikan menggunakan Opsi 2 sebagai de facto untuk sebagian besar karena tidak super mahal.
Kasus 1: log.debug ("satu string")
Case2: log.debug ("satu string" + "dua string" + object.toString + object2.toString)
Pada saat salah satu dari ini disebut, string parameter dalam log.debug (baik itu KASUS 1 atau Case2) HARUS dievaluasi. Itulah yang dimaksud semua orang dengan 'mahal.' Jika Anda memiliki kondisi sebelumnya, 'isDebugEnabled ()', ini tidak harus dievaluasi di mana kinerja disimpan.
sumber
Pada 2.x, Apache Log4j memiliki pemeriksaan ini bawaan, jadi
isDebugEnabled()
tidak perlu lagi. Lakukan sajadebug()
dan pesan akan ditekan jika tidak diaktifkan.sumber
Log4j2 memungkinkan Anda memformat parameter ke dalam templat pesan, mirip dengan
String.format()
, sehingga tidak perlu lagi dilakukanisDebugEnabled()
.Contoh log4j2.properties sederhana:
sumber