patternjavaMinor
Efficiently return a ChatColor
Viewed 0 times
returnefficientlychatcolor
Problem
I am working on a plugin for a Minecraft server. In it, I have a function that returns a
Whenever I need reference the user with proper colors, I always get a color from the below function.
One might call this function as below:
And it would send a message to the player like "Welcome back, (playerName)!" with playerName the level's color.
What I have found is that if you have the first permission level (
Is there any way to improve my function run at nearly the same speed for all of my checks?
(I am a beginner at Java, but know many other languages, so this is somewhat ne
ChatColor depending on what permission level you are.Whenever I need reference the user with proper colors, I always get a color from the below function.
/**
* ChatColor
*
* @param Player
* @return ChatColor
*/
public ChatColor getColor(Player p) {
// By default the color is Guest. The color will stay at guest otherwise.
ChatColor color = ChatColor.GRAY;
if (p.hasPermission("level.owner")) {
// Owner
color = ChatColor.RED;
} else if (p.hasPermission("level.staff")) {
// Admin / Mod
color = ChatColor.AQUA;
} else if (p.hasPermission("level.builder")) {
// Builder
color = ChatColor.DARK_AQUA;
} else if (p.hasPermission("level.member")) {
// Member
color = ChatColor.GOLD;
} else if (p.hasPermission("level.guest")) {
// Guest
// We don't need to change the color, since the color defaults to gray.
}
return color;
}One might call this function as below:
p.sendMessage("Welcome back, " + getColor(p) + p.getName() + gold + "!");And it would send a message to the player like "Welcome back, (playerName)!" with playerName the level's color.
What I have found is that if you have the first permission level (
level.owner) it can take a much longer time. After putting in some debugging (e.g getting a NanoTime, running my function, and subtracting the difference) I've found the following:- With
level.ownerit takes about 4580ns to run
- With
level.staffit takes about 6340ns to run
- With
level.builderit takes about 8000ns to run
- With
level.memberit takes about 7630ns (sometimes going as high as 10240ns) to run
- With
level.guestit takes about 10000ns+ to run
Is there any way to improve my function run at nearly the same speed for all of my checks?
(I am a beginner at Java, but know many other languages, so this is somewhat ne
Solution
I'm guessing that you call this method frequently. If so, you might consider memoizing the result. Something like
in the class. Possibly make this
with
And then before the
I don't know if this is faster or not. In the typical case, it will just do a single hash access. If that is fast, then it's faster. If that's slow, then it might not be.
There's also the problem that if the permissions change, this won't adjust. I'm assuming that this will be rare enough not to matter. If that's not so, you might need to find a way to invalidate the caching when permissions change. Of course, if you invalidate too often, you lose the benefits of caching. The first call to this method will be slower. It's the subsequent calls that this might help.
private Map playerChatColors = new HashMap<>();in the class. Possibly make this
static. And then at the beginning of the method, replace ChatColor color = ChatColor.GRAY;with
ChatColor color = playerChatColors.get(p);
if (color != null) {
return color;
}
color = ChatColor.GRAY;And then before the
return at the end, add something like playerChatColors.put(p, color);I don't know if this is faster or not. In the typical case, it will just do a single hash access. If that is fast, then it's faster. If that's slow, then it might not be.
There's also the problem that if the permissions change, this won't adjust. I'm assuming that this will be rare enough not to matter. If that's not so, you might need to find a way to invalidate the caching when permissions change. Of course, if you invalidate too often, you lose the benefits of caching. The first call to this method will be slower. It's the subsequent calls that this might help.
Code Snippets
private Map<Player, ChatColor> playerChatColors = new HashMap<>();ChatColor color = ChatColor.GRAY;ChatColor color = playerChatColors.get(p);
if (color != null) {
return color;
}
color = ChatColor.GRAY;playerChatColors.put(p, color);Context
StackExchange Code Review Q#117313, answer score: 7
Revisions (0)
No revisions yet.