From 2fb7e8f002795eeea72b7a7c00483a2e3c48ac40 Mon Sep 17 00:00:00 2001 From: Kevin Schmidt Date: Tue, 2 Jan 2024 19:18:40 -0800 Subject: [PATCH] Issue #4: Changes to improve performance --- pom.xml | 2 +- .../org/goochjs/glicko2/RatingCalculator.java | 6 +- .../goochjs/glicko2/RatingPeriodResults.java | 57 ++++++++++++------- .../java/org/goochjs/glicko2/TestGlicko2.java | 30 ++++++++++ 4 files changed, 71 insertions(+), 24 deletions(-) diff --git a/pom.xml b/pom.xml index ce094fd..dbf45a2 100644 --- a/pom.xml +++ b/pom.xml @@ -7,7 +7,7 @@ org.goochjs goochjs-glicko2 - 0.0.1-SNAPSHOT + 0.0.2-SNAPSHOT bundle Glicko-2 rating system glicko2 diff --git a/src/main/java/org/goochjs/glicko2/RatingCalculator.java b/src/main/java/org/goochjs/glicko2/RatingCalculator.java index 081ef04..1b14f09 100644 --- a/src/main/java/org/goochjs/glicko2/RatingCalculator.java +++ b/src/main/java/org/goochjs/glicko2/RatingCalculator.java @@ -61,8 +61,10 @@ public RatingCalculator( */ public void updateRatings(RatingPeriodResults results) { for ( Rating player : results.getParticipants() ) { - if ( results.getResults(player).size() > 0 ) { - calculateNewRating(player, results.getResults(player)); + List playerResults = results.getResults(player); + + if ( !playerResults.isEmpty() ) { + calculateNewRating(player, playerResults); } else { // if a player does not compete during the rating period, then only Step 6 applies. // the player's rating and volatility parameters remain the same but deviation increases diff --git a/src/main/java/org/goochjs/glicko2/RatingPeriodResults.java b/src/main/java/org/goochjs/glicko2/RatingPeriodResults.java index 3a7af75..27b958f 100644 --- a/src/main/java/org/goochjs/glicko2/RatingPeriodResults.java +++ b/src/main/java/org/goochjs/glicko2/RatingPeriodResults.java @@ -7,8 +7,11 @@ package org.goochjs.glicko2; import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; import java.util.HashSet; import java.util.List; +import java.util.Map; import java.util.Set; /** @@ -17,7 +20,7 @@ * @author Jeremy Gooch */ public class RatingPeriodResults { - private List results = new ArrayList(); + private Map> results = new HashMap>(); private Set participants = new HashSet(); @@ -44,9 +47,7 @@ public RatingPeriodResults(Set participants) { * @param loser */ public void addResult(Rating winner, Rating loser) { - Result result = new Result(winner, loser); - - results.add(result); + this.addResult(new Result(winner, loser)); } @@ -57,12 +58,31 @@ public void addResult(Rating winner, Rating loser) { * @param player2 */ public void addDraw(Rating player1, Rating player2) { - Result result = new Result(player1, player2, true); - - results.add(result); + this.addResult(new Result(player1, player2, true)); } - - + + + private void addResult(Result result) { + List playerResults = results.get(result.getWinner()); + + if (playerResults == null) { + playerResults = new ArrayList(); + results.put(result.getWinner(), playerResults); + } + + playerResults.add(result); + + playerResults = results.get(result.getLoser()); + + if (playerResults == null) { + playerResults = new ArrayList(); + results.put(result.getLoser(), playerResults); + } + + playerResults.add(result); + } + + /** * Get a list of the results for a given player. * @@ -70,15 +90,13 @@ public void addDraw(Rating player1, Rating player2) { * @return List of results */ public List getResults(Rating player) { - List filteredResults = new ArrayList(); - - for ( Result result : results ) { - if ( result.participated(player) ) { - filteredResults.add(result); - } + List playerResults = results.get(player); + + if (playerResults != null) { + return playerResults; } - - return filteredResults; + + return Collections.emptyList(); } @@ -89,10 +107,7 @@ public List getResults(Rating player) { */ public Set getParticipants() { // Run through the results and make sure all players have been pushed into the participants set. - for ( Result result : results ) { - participants.add(result.getWinner()); - participants.add(result.getLoser()); - } + participants.addAll(results.keySet()); return participants; } diff --git a/src/test/java/org/goochjs/glicko2/TestGlicko2.java b/src/test/java/org/goochjs/glicko2/TestGlicko2.java index 8dbe417..064a264 100644 --- a/src/test/java/org/goochjs/glicko2/TestGlicko2.java +++ b/src/test/java/org/goochjs/glicko2/TestGlicko2.java @@ -6,6 +6,9 @@ */ package org.goochjs.glicko2; +import java.util.ArrayList; +import java.util.List; + import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; @@ -79,4 +82,31 @@ private void printResults(String text) { System.out.println(player4); System.out.println(player5); } + + @Test + public void scaleTest() { + int playerCount = 100000; + List players = new ArrayList(playerCount); + + results = new RatingPeriodResults(); + + for (int i = 0; i < playerCount; i++) { + Rating player = new Rating("player" + i, ratingSystem); + player.setRating(1000.0 + i % 1000); + players.add(player); + } + + long start = System.currentTimeMillis(); + + for (int i = 0; i < playerCount; i++) { + results.addResult(players.get(i), players.get((i + 1) % playerCount)); + results.addResult(players.get(i), players.get((i + 2) % playerCount)); + } + + ratingSystem.updateRatings(results); + + long end = System.currentTimeMillis(); + + System.out.println("Execution time: " + (end - start)); + } }