HiveBrain v1.2.0
Get Started
← Back to all entries
patternjavaMinor

Efficiently return a ChatColor

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
returnefficientlychatcolor

Problem

I am working on a plugin for a Minecraft server. In it, I have a function that returns a 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.owner it takes about 4580ns to run



  • With level.staff it takes about 6340ns to run



  • With level.builder it takes about 8000ns to run



  • With level.member it takes about 7630ns (sometimes going as high as 10240ns) to run



  • With level.guest it 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

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.