Rumah >Java >javaTutorial >Tingkatkan Prestasi Belakang Java Anda: Petua Pengoptimuman Penting!
Prestasi memainkan peranan penting dalam kejayaan projek perisian. Pengoptimuman yang digunakan semasa pembangunan back-end Java memastikan penggunaan sumber sistem yang cekap dan meningkatkan kebolehskalaan aplikasi anda.
Dalam artikel ini, saya akan berkongsi dengan anda beberapa teknik pengoptimuman yang saya anggap penting untuk mengelakkan kesilapan biasa.
Memilih struktur data yang cekap boleh meningkatkan prestasi aplikasi anda dengan ketara, terutamanya apabila berurusan dengan set data yang besar atau operasi kritikal masa. Menggunakan struktur data yang betul meminimumkan masa capaian, mengoptimumkan penggunaan memori dan mengurangkan masa pemprosesan.
Sebagai contoh, apabila anda perlu kerap mencari dalam senarai, menggunakan HashSet dan bukannya ArrayList boleh menghasilkan hasil yang lebih pantas:
// Inefficient - O(n) complexity for contains() check List<String> names = new ArrayList<>(); names.add("Alice"); names.add("Bob"); // Checking if "Alice" exists - time complexity O(n) if (names.contains("Alice")) { System.out.println("Found Alice"); } // Efficient - O(1) complexity for contains() check Set<String> namesSet = new HashSet<>(); namesSet.add("Alice"); namesSet.add("Bob"); // Checking if "Alice" exists - time complexity O(1) if (namesSet.contains("Alice")) { System.out.println("Found Alice"); }
Dalam contoh ini, HashSet menyediakan purata kerumitan masa O(1) untuk operasi contains(), manakala ArrayList memerlukan O(n) kerana ia mesti berulang melalui senarai. Oleh itu, untuk carian yang kerap, HashSet adalah lebih cekap daripada ArrayList.
Sebenarnya, jika anda ingin tahu apa itu kerumitan masa: Kerumitan Masa merujuk kepada cara masa berjalan sesuatu algoritma berbeza dengan saiz input. Ini membantu kami memahami seberapa pantas algoritma berjalan dan biasanya menunjukkan cara ia berkelakuan dalam kes yang paling teruk. Kerumitan masa biasanya dilambangkan dengan Notasi Big O.
Anda boleh mengelakkan overhed pemprosesan yang tidak perlu dengan menyemak medan yang akan digunakan dalam kaedah yang tidak sepatutnya batal pada permulaan kaedah. Adalah lebih berkesan dari segi prestasi untuk menyemaknya pada mulanya, dan bukannya menyemak semakan batal atau syarat yang menyalahi undang-undang dalam langkah-langkah seterusnya dalam kaedah.
public void processOrder(Order order) { if (Objects.isNull(order)) throw new IllegalArgumentException("Order cannot be null"); if (order.getItems().isEmpty()) throw new IllegalStateException("Order must contain items"); ... // Process starts here. processItems(order.getItems()); }
Seperti yang ditunjukkan oleh contoh ini, kaedah mungkin mengandungi proses lain sebelum sampai ke kaedah processItems. Walau apa pun, senarai Item dalam objek Pesanan diperlukan untuk kaedah processItems berfungsi. Anda boleh mengelakkan pemprosesan yang tidak perlu dengan menyemak keadaan pada permulaan proses.
Mencipta objek yang tidak diperlukan dalam aplikasi Java boleh menjejaskan prestasi secara negatif dengan meningkatkan masa Kutipan Sampah. Contoh yang paling penting ialah penggunaan String.
Ini kerana kelas String di Jawa tidak boleh diubah. Ini bermakna setiap pengubahsuaian String baharu mencipta objek baharu dalam ingatan. Ini boleh menyebabkan kehilangan prestasi yang serius, terutamanya dalam gelung atau apabila berbilang gabungan dilakukan.
Cara terbaik untuk menyelesaikan masalah ini ialah menggunakan StringBuilder. StringBuilder boleh mengubah suai String yang sedang diusahakannya dan melakukan operasi pada objek yang sama tanpa mencipta objek baharu setiap kali, menghasilkan hasil yang lebih cekap.
Sebagai contoh, dalam serpihan kod berikut, objek String baharu dicipta untuk setiap operasi penggabungan:
// Inefficient - O(n) complexity for contains() check List<String> names = new ArrayList<>(); names.add("Alice"); names.add("Bob"); // Checking if "Alice" exists - time complexity O(n) if (names.contains("Alice")) { System.out.println("Found Alice"); } // Efficient - O(1) complexity for contains() check Set<String> namesSet = new HashSet<>(); namesSet.add("Alice"); namesSet.add("Bob"); // Checking if "Alice" exists - time complexity O(1) if (namesSet.contains("Alice")) { System.out.println("Found Alice"); }
Dalam gelung di atas, objek String baharu dicipta dengan setiap hasil = operasi. Ini meningkatkan penggunaan memori dan masa pemprosesan.
Kita boleh mengelakkan penciptaan objek yang tidak perlu dengan melakukan perkara yang sama dengan StringBuilder. StringBuilder meningkatkan prestasi dengan mengubah suai objek sedia ada:
public void processOrder(Order order) { if (Objects.isNull(order)) throw new IllegalArgumentException("Order cannot be null"); if (order.getItems().isEmpty()) throw new IllegalStateException("Order must contain items"); ... // Process starts here. processItems(order.getItems()); }
Dalam contoh ini, hanya satu objek dibuat menggunakan StringBuilder dan operasi dilakukan pada objek ini sepanjang gelung. Akibatnya, manipulasi rentetan selesai tanpa mencipta objek baharu dalam ingatan.
Fungsi flatMap yang disertakan dengan Java Stream API ialah alat berkuasa untuk mengoptimumkan operasi pada koleksi. Gelung bersarang boleh menyebabkan kehilangan prestasi dan kod yang lebih kompleks. Dengan menggunakan kaedah ini, anda boleh menjadikan kod anda lebih mudah dibaca dan memperoleh prestasi.
peta: Beroperasi pada setiap elemen dan mengembalikan elemen lain sebagai hasilnya.
flatMap: Beroperasi pada setiap elemen, menukar keputusan kepada struktur rata dan menyediakan struktur data yang lebih mudah.
Dalam contoh berikut, operasi dilakukan dengan senarai menggunakan gelung bersarang. Apabila senarai berkembang, operasi akan menjadi lebih tidak cekap.
String result = ""; for (int i = 0; i < 1000; i++) result += "number " + i;
Dengan menggunakan flatMap, kita boleh menyingkirkan gelung bersarang dan mendapatkan struktur yang lebih bersih dan berprestasi.
StringBuilder result = new StringBuilder(); for (int i = 0; i < 1000; i++) result.append("number ").append(i); String finalResult = result.toString();
Dalam contoh ini, kami menukar setiap senarai menjadi strim rata dengan FlatMap dan kemudian memproses elemen dengan forEach. Kaedah ini menjadikan kod lebih pendek dan lebih cekap prestasi.
Mengembalikan data yang ditarik daripada pangkalan data secara langsung kerana kelas Entiti boleh membawa kepada pemindahan data yang tidak perlu. Ini adalah kaedah yang sangat salah dari segi keselamatan dan prestasi. Sebaliknya, menggunakan DTO untuk mengembalikan hanya data yang diperlukan meningkatkan prestasi API dan menghalang pemindahan data besar yang tidak perlu.
List<List<String>> listOfLists = new ArrayList<>(); for (List<String> list : listOfLists) { for (String item : list) { System.out.println(item); } }
Prestasi pangkalan data secara langsung mempengaruhi kelajuan aplikasi. Pengoptimuman prestasi amat penting apabila mendapatkan semula data antara jadual yang berkaitan. Pada ketika ini, anda boleh mengelakkan pemuatan data yang tidak perlu dengan menggunakan EntityGraph dan Lazy Fetching. Pada masa yang sama, pengindeksan yang betul dalam pertanyaan pangkalan data secara mendadak meningkatkan prestasi pertanyaan.
EntityGraph membolehkan anda mengawal data yang berkaitan dalam pertanyaan pangkalan data. Anda hanya menarik data yang anda perlukan, mengelakkan kos pengambilan yang tidak sabar-sabar.
Eager Fetching ialah apabila data dalam jadual berkaitan secara automatik disertakan dengan pertanyaan.
// Inefficient - O(n) complexity for contains() check List<String> names = new ArrayList<>(); names.add("Alice"); names.add("Bob"); // Checking if "Alice" exists - time complexity O(n) if (names.contains("Alice")) { System.out.println("Found Alice"); } // Efficient - O(1) complexity for contains() check Set<String> namesSet = new HashSet<>(); namesSet.add("Alice"); namesSet.add("Bob"); // Checking if "Alice" exists - time complexity O(1) if (namesSet.contains("Alice")) { System.out.println("Found Alice"); }
Dalam contoh ini, data berkaitan alamat dan maklumat pengguna diambil dalam pertanyaan yang sama. Pertanyaan tambahan yang tidak perlu dielakkan.
Tidak seperti Eager Fetch, Lazy Fetch mengambil data daripada jadual berkaitan hanya apabila diperlukan.
public void processOrder(Order order) { if (Objects.isNull(order)) throw new IllegalArgumentException("Order cannot be null"); if (order.getItems().isEmpty()) throw new IllegalStateException("Order must contain items"); ... // Process starts here. processItems(order.getItems()); }
Pengindeksan ialah salah satu kaedah paling berkesan untuk meningkatkan prestasi pertanyaan pangkalan data. Jadual dalam pangkalan data terdiri daripada baris dan lajur, dan apabila pertanyaan dibuat, selalunya perlu untuk mengimbas semua baris. Pengindeksan mempercepatkan proses ini, membolehkan pangkalan data mencari dengan lebih pantas pada medan tertentu.
Caching ialah proses menyimpan sementara data yang kerap diakses atau hasil pengiraan dalam kawasan storan pantas seperti memori. Caching bertujuan untuk memberikan maklumat ini dengan lebih cepat apabila data atau hasil pengiraan diperlukan lagi. Terutamanya dalam pertanyaan pangkalan data dan transaksi dengan kos pengiraan yang tinggi, penggunaan cache boleh meningkatkan prestasi dengan ketara.
Anotasi @Cacheable Spring Boot menjadikan penggunaan cache sangat mudah.
String result = ""; for (int i = 0; i < 1000; i++) result += "number " + i;
Dalam contoh ini, apabila kaedah findUserById dipanggil buat kali pertama, maklumat pengguna diambil daripada pangkalan data dan disimpan dalam cache. Apabila maklumat pengguna yang sama diperlukan sekali lagi, ia diambil daripada cache tanpa pergi ke pangkalan data.
Anda juga boleh menggunakan penyelesaian caching bertaraf tinggi seperti Redis untuk keperluan projek anda.
Anda boleh membangunkan aplikasi yang lebih pantas, lebih cekap dan berskala menggunakan teknik pengoptimuman ini, terutamanya dalam projek bahagian belakang anda yang dibangunkan dengan Java.
...
Terima kasih kerana membaca artikel saya! Jika anda mempunyai sebarang soalan, maklum balas atau pendapat yang ingin anda kongsikan, saya ingin mendengarnya dalam ulasan.
Anda boleh mengikuti saya di Dev.to untuk mendapatkan maklumat lanjut tentang topik ini dan siaran saya yang lain. Jangan lupa untuk menyukai siaran saya untuk membantu mereka menjangkau lebih ramai orang!
Untuk mengikuti saya di LinkedIn: tamerardal
Sumber:
Atas ialah kandungan terperinci Tingkatkan Prestasi Belakang Java Anda: Petua Pengoptimuman Penting!. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!