问题:
Snack类的isExpired方法实现了什么功能?
现有相当大量的snack对象(如一个长度100万的Snack对象数组)需要执行isExpired方法,执行时候发现效率低下, 请分析原因, 并给出优化方案?
为了方便交流学习, 我把完整的题目都贴出来了, 我主要的问题是第二问, 大家有没有好的办法?
代码如下:
public class Snack {
public Snack(String name, Date expirDate){
this.name = name;
this.expireDate = expireDate;
}
private String name;
private Date expireDate;
public boolean isExpired(){
Date now = new Date();
return now.compareTo(this.expireDate) > 0 ;
}
}
Terima kasih atas jemputan.
Ini boleh didapati di Baidu. Mengembalikan benar jika tarikh semasa lebih besar daripada expireDate objek.
Algoritma saya tidak begitu baik Jika terdapat sebarang kesilapan, sila komen: pertimbangkan dahulu sama ada tarikh luput objek adalah teratur. Tertib boleh belajar daripada idea carian binari. Sebagai contoh, dari kecil ke besar, jika objek boleh ditemui, semua objek berikutnya akan kembali benar.
Pertama sekali, anda boleh melihat pelaksanaan dalaman kaedah
Date
objekcompareTo
Akan ada operasiclone
, yang akan meningkatkan overhed.1. Fungsi kaedah
2. Memandangkan ungkapan ini agak samar-samar, saya akan menerangkannya dalam dua situasi:isExpired
adalah untuk menentukan sama ada objek semasa telah tamat tempoh.expireDate
2.1 Tatasusunan Snek dengan panjang 100W, melintasi dan melaksanakan kaedah
, soalan mungkin memeriksa memori JVM. pengurusan dan mekanisme pengumpulan sampah, kerana program ini akan
isExpired
secara bersiri melaksanakan kaedah bagi 1 juta objek ini (dengan mengandaikan bahawa kos untuk mencipta objek ini diabaikan), dan setiap kali ia dijalankan, satuisExpired
objek akan dibuat, danDate
Secara dalaman,compareTo
akan diklon, jadi overhead akan menjadi agak besar;this.expireDate
2.2 Dalam tempoh masa tertentu, terdapat sejumlah besar objek Snekmelaksanakan kaedah selari , jadi soalan tertumpu pada Ujian mungkin mengenai pemprosesan serentak tinggi Jika anda juga boleh menyentuh mata pengetahuan 2.1, anda boleh mendapatkan mata tambahan;
isExpired
Secara peribadi, saya rasa kebarangkalian 2.2 adalah lebih tinggi.Bercakap tentang pemahaman pengoptimuman saya tentang kod ini:
1 Gunakanatau
(apabila keperluan ketepatan tidak tinggi) untuk menyimpan
long
, jikaint
2.1expireDate
, maka anda boleh menyusun di luar kaedah (dengan mengandaikan bahawa keperluan ketepatan masa tidak terlalu tinggi), dan kemudian dalam kaedah anda hanya perlu membandingkan nilaiDate now = new Date()
danisExperied
jika ia adalahnow.getTime()
2.2expireDate
dan aplikasi digunakan dalam persekitaran kluster, maka objek tidak boleh dijana dalam , kerana walaupun terdapat penyegerakan masa antara pelayan, ketidakkonsistenan masa mungkin berlaku, contohnya , mesin A dan Mungkin juga perbezaan antara mesin B dan mesin B ialah 1 saat. Pada masa ini, anda boleh menggunakan penjana masa global, dan kemudian aplikasi memanggil penjana ini untuk mendapatkan masa pelayan semasa untuk perbandinganisExpired
2. Sahkan ketepatan masa tamatDate
dari perspektif perniagaan; , iaitu [tahun |. Bulan|Hari|Jam|Minit|Kedua|Millisaat]?, strategi penyimpanan dan perbandingan bagi ketepatan yang berbeza juga boleh berbeza.Tulisan agak bersepah.
Jika terdapat sejumlah besar data, ia akan memakan masa untuk mendapatkan masa bagi setiap satu dalam
isExpired()
.Memandangkan
isExpired()
setiap objek dalam tatasusunan dipanggil secara berurutan pada masa yang sama, ia boleh diandaikan bahawa perbandingan dilakukan pada masa yang sama, kemudian tambahkan lebihanisExpired()
kepadaAnda boleh melakukan ini apabila memanggil
Bandingkan masa dengan
System.currentTimeMillis()
Tukar tatasusunan menjadi baris gilir keutamaan Setiap kali anda hanya perlu melaksanakan isExpired() pada elemen atas timbunan, prestasi dipertingkatkan daripada O(n) kepada O(1)
Sekarang saya melihat sesuatu yang selari, saya mahu menggunakan API Java 8 baharu, aliran selari, haha, jadi saya hanya mengamalkannya, untuk rujukan sahaja
Bandingkan menggunakan kaedah tradisional compareTo of Date
Bandingkan menggunakan kaedah
System.currentTimeMillis() > expiredDate.getTime()
TarikhSetiap kaedah perbandingan dilaksanakan 5 kali untuk memudahkan perbandingan Pada masa yang sama, setiap kaedah menggunakan 3 mod untuk pelaksanaan
untuk mod pelaksanaan gelung
Mod pelaksanaan gelung strim
Mod pelaksanaan gelung strim selari
Kod adalah serupa dengan ini:
Keputusan pelaksanaan akhir adalah seperti berikut:
1 juta tahap
][2]
Tahap 1000w
Ringkasnya: Saya merasakan bahawa kaedah perbandingan masa perlu diubah atau tidak, berdasarkan kod ujian, ia akan memberi sedikit kesan (ia mungkin juga berkaitan dengan persekitaran sebenar yang khusus). kaedah aliran, kecekapan pelaksanaan sememangnya bertambah baik Apabila mengendalikan sejumlah besar tatasusunan atau koleksi, kaedah aliran selari adalah lebih baik
Terdapat dua titik pengoptimuman
1: Penciptaan objek Tarikh
2 kaedah compareTo()
Dikatakan dalam soalan bahawa "pada masa ini terdapat sejumlah besar objek snek (seperti susunan objek Snek dengan panjang 1 juta) yang perlu melaksanakan kaedah isExpired, dan kecekapan didapati rendah semasa pelaksanaan"
Terdapat dua masalah teras di sini, dan saya tidak tahu yang mana satu untuk diselesaikan.
Mahu menyelesaikan sejumlah besar objek?
2. Untuk menyelesaikan ketidakcekapan pelaksanaan.
Soalan 1,
Kosongkan tatasusunan 10,000 objek. Tidak banyak yang perlu dilakukan.
Soalan 2,
Padamkan kod yang dilaksanakan dalam kaedah isExpire() Kaedah ini tidak melakukan apa-apa dan kecekapan pelaksanaan akan menjadi tinggi.