I am creating a mock Twitter project which loads user data from a somewhat large text file containing ~3.6 million lines formatted like this:
0 12
0 32
1 9
1 54
2 33
etc...
The first string token is the userId and the second is the followId.
The first half of this helper method takes in the current user's ID, checks to see if it exists and creates a new user if necessary. After that, the followId is added to this new or existing user's following list of type ArrayList<Integer>.
With ~3.6 million lines to read, this doesn't take long (9868 ms).
Now the second half creates or finds the followed user (followId) and adds the userId to their followers list, but this additional code extends the amount of time to read the file exponentially (172744 ms).
I tried using the same TwitterUser object throughout the method. All of the adding methods (follow, addFollower) are simple ArrayList.add() methods. Is there anything I can do to make this method more efficient?
Please note: While this is school-related, I'm not asking for an answer to my solution. My professor permitted this slow object initialization, but I'd like to understand how I can make it faster.
private Map<Integer, TwitterUser> twitterUsers = new HashMap<Integer, TwitterUser>();
private void AddUser(int userId, int followId){
TwitterUser user = getUser(userId);
if (user == null){
user = new TwitterUser(userId);
user.follow(followId);
twitterUsers.putIfAbsent(userId, user);
} else{
user.follow(followId);
}
//adding the code below, slows the whole process enormously
user = getUser(followId);
if (user == null){
user = new TwitterUser(followId);
user.addFollower(userId);
twitterUsers.putIfAbsent(followId, user);
} else{
user.addFollower(userId);
}
}
private TwitterUser getUser(int id){
if (twitterUsers.isEmpty()) return null;
return twitterUsers.get(id);
}
twitterUsers.isEmpty()in#getUser,Map#getreturnsnullif the specified key is not found. This won't substantially reduce runtime but it is redundant. Could you also post theTwitterUser#followandTwitterUser#addFollowercode?putIfAbsentis a HashMap method andfollowis simply: 1.) check if !ArrayList.contains(int) ... 2.) ArrayList.add(int) @JonnyHenlyisEmpty()check.. silly of meputIfAbsentwas a method ofHashMap. Have you considered using anotherHashMapinstead of anArrayList, since the lookup time for anArrayListis linear?