问题:
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 ;
}
}
Merci pour l'invitation.
Ceci peut être trouvé sur Baidu. Renvoie vrai si la date actuelle est supérieure à la date d'expiration de l'objet.
Mon algorithme n'est pas très bon. S'il y a une erreur, veuillez commenter : vérifiez d'abord si la date d'expiration des objets est en ordre. Orderly peut apprendre de l’idée de la recherche binaire. Par exemple, de petit à grand, si un objet peut être trouvé, tous les objets suivants renverront vrai.
Tout d'abord, vous pouvez jeter un œil à l'implémentation interne de la méthode
Date
de l'objetcompareTo
Il y aura desclone
opérations, ce qui augmentera la surcharge.1. La fonction de la méthode
isExpired
est de déterminer si l'objet actuel a expiré. SiexpireDate
est antérieur à l'heure actuelle du serveur, il est considéré comme n'ayant pas expiré, sinon il est considéré comme ayant expiré ;2. Cette expression étant un peu ambiguë, je vais l'expliquer dans deux situations :
Personnellement, je pense que la probabilité de 2,2 est plus élevée.2.1 Un tableau Snack d'une longueur de 100W, parcourant et exécutant la méthode
isExpired
, la question peut examiner la mémoire JVM. gestion et mécanisme de collecte des déchets, car le programme en série exécutera lesisExpired
méthodes de ces 1 million d'objets (en supposant que le coût de création de ces objets soit ignoré), et à chaque exécution, un nouveauDate
l'objet sera créé, etcompareTo
En interne,this.expireDate
sera cloné, donc la surcharge sera relativement importanteDans un certain laps de temps, il y aura un grand nombre d'objets Snack exécuter la méthode en parallèle , donc la question se concentre sur le test peut être un traitement à haute concurrence. Si vous pouvez également aborder les points de connaissance de 2.1, vous pouvez obtenir des points supplémentaires
isExpired
.1. Utilisez
L'écriture est plutôt brouillonne.ou
long
(lorsque les exigences de précision ne sont pas élevées) pour stockerint
, s'il s'agit deexpireDate
2.1 , alors vous pouvez empiler en dehors de la méthode (en supposant que les exigences de précision temporelle ne sont pas très élevées), puis dans la méthodeDate now = new Date()
il vous suffit de comparer les valeurs deisExperied
etnow.getTime()
si ; il s'agit deexpireDate
2.2 et l'application est déployée dans un environnement cluster, alors l'objet ne peut pas être généré dansisExpired
, car même s'il y a une synchronisation horaire entre les serveurs, des incohérences horaires peuvent survenir par exemple , machine A et Il est également possible que la différence entre la machine B et la machine B soit de 1 seconde. À ce stade, vous pouvez utiliser un générateur d'heure global, puis l'application appelle ce générateur pour obtenir l'heure actuelle du serveur à des fins de comparaisonDate
2 Confirmez l'exactitude dudélai d'expiration du point de vue commercial ; , qui est [année | Mois | Jour | Heure | Minute | Seconde | Milliseconde] ?, les stratégies de stockage et de comparaison des différentes précisions peuvent également être différentes. Plus la précision est élevée, plus le coût est élevé.
S'il y a une grande quantité de données, il faudra beaucoup de temps pour obtenir l'heure de chacune d'elles dans
isExpired()
.Puisque
isExpired()
de chaque objet du tableau est appelé séquentiellement en même temps, on peut supposer que la comparaison est effectuée en même temps, puis ajouter une surchargeisExpired()
àVous pouvez le faire lorsque vous appelez
Comparez le temps avec
System.currentTimeMillis()
Changez le tableau en file d'attente prioritaire. Chaque fois que vous devez uniquement exécuter isExpired() sur l'élément supérieur du tas, les performances sont améliorées de O(n) à O(1)
Maintenant que je vois quelque chose de parallèle, je veux utiliser la nouvelle API de Java 8, flux parallèle, haha, donc je l'ai simplement pratiqué, pour référence seulement
Comparez en utilisant la méthode traditionnelle compareTo de Date
Comparez en utilisant la méthode
System.currentTimeMillis() > expiredDate.getTime()
de DateChaque méthode de comparaison est exécutée 5 fois pour faciliter la comparaison. En même temps, chaque méthode utilise 3 modes d'exécution
pour le mode d'exécution de boucle
Mode d'exécution de boucle de flux
Mode d'exécution de boucle de flux parallèle
Le code est similaire à ceci :
Le résultat final de l'exécution est le suivant :
Niveau 1 million
][2]
Niveau 1000w
Pour résumer : je pense que la méthode de comparaison du temps devrait être modifiée ou non. À en juger par le code du test, cela aura peu d'impact (cela peut aussi être lié à l'environnement réel spécifique. Cependant, après avoir adopté le parallèle). méthode de flux, l'efficacité d'exécution s'est en effet améliorée. Lors de l'exploitation d'un grand nombre de tableaux ou de collections, la méthode de flux parallèle est meilleure. Le JDK déterminera le meilleur mode de concurrence en fonction de l'environnement spécifique
.Il y a deux points d'optimisation
.1 : Création de l'objet Date
2 Méthode compareTo()
Il est dit dans la question qu '"il existe actuellement un grand nombre d'objets snack (tels qu'un tableau d'objets Snack d'une longueur de 1 million) qui doivent exécuter la méthode isExpired, et l'efficacité s'avère faible pendant l'exécution"
Il y a deux problèmes fondamentaux ici, et je ne sais pas lequel résoudre.
Vous allez résoudre un grand nombre d'objets ?
2. Pour résoudre l’inefficacité de l’exécution.
Question 1,
Effacer le tableau de 10 000 objets. Il n’y a tout simplement pas grand-chose à faire.
Question 2,
Supprimez le code exécuté dans la méthode isExpire() Cette méthode ne fait rien et l'efficacité d'exécution sera élevée.