Is there performance gain using . replace() instead of . put() in a Map?

Asked

Viewed 141 times

1

Is there any performance gain using the method .replace() instead of using .put() in a Map.

Studying Maps I noticed that the method .put() and .replace() have practically the same function. I made a simple code and tested and the resulting was the same in both cases:

public static HashMap<String, String> Lista = new HashMap<String, String>();

public void methodTeste(String teste, String outra) {
    if (Lista.containsKey(teste)) {
        Lista.replace(teste, outra);
    } else {
        Lista.put(teste, outro);
    }
}

public void methodTeste(String teste, String outra) {
    Lista.put(teste, outro);
}

Which of the two codes will get better performance?

  • Did any of the answers solve your question? Do you think you can accept one of them? Check out the [tour] how to do this, if you haven’t already. You would help the community by identifying what was the best solution for you. You can accept only one of them. But you can vote on any question or answer you find useful on the entire site

4 answers

4

replace() is more efficient in cases where there is no key being used in it. It can only replace a value from an existing key, executes nothing if it does not have the key. Already the put() will place a value there, if the key exists it will be equal to the replace(), but if it does not exist you will have to create the key on the map, which has extra cost.

But performance should not be considered, the important thing is the semantics that wants to give, they give different results in certain circumstances, as shown above, so I use what you need.

In this example the test makes no sense (obviously that the first will be slower, it does much more and gives different result to the second, it makes no sense to compare these two things). If you only want to change the value if the key exists and not create a new one, use the replace(). To get the same result with put() would have to do so:

if (Lista.containsKey(teste)) lista.put(teste, outro);

which is the same as:

lista.replace(teste, outra);

Documentation.

The proper test would be thus:

import java.util.*;

class Main {
    public static HashMap<String, String> lista = new HashMap<>();
    
    private static void Put(String teste, String outra) {
        for (int i = 0; i < 100000; i++) if (lista.containsKey("antonio")) lista.put(teste, outra);
    }
    
    private static void Replace(String teste, String outra) {
        for (int i = 0; i < 100000; i++) lista.replace(teste, outra);
    }
    
    public static void main(String[] args) {
        long inicio = System.currentTimeMillis();
        Put("antonio", "antonio");
        System.out.println("Put: " + (System.currentTimeMillis() - inicio)  + " ms");
        inicio = System.currentTimeMillis();
        Replace("antonio", "antonio");
        System.out.println("Replace: " + (System.currentTimeMillis() - inicio) + " ms");
    }
}

Behold working in the ideone. And in the repl it.. Also put on the Github for future reference.

  • I think the . replace should only be used in cases where the user is sure the KEY exists... in my case where I do not know if the KEY already exists is much better to use . put right... Doing the tests proposed by Antonio Santos this was very noticeable the performance gained using . direct put instead of doing the checks. But thanks for learning!

  • 2

    No, it depends on what the person wants, it doesn’t depend on whether they’re sure, they might want you to do anything when the key doesn’t exist, so the replace() is the stand of what is saying, the put() even would be the case to know used if he is sure of existence if she does not want to create a new key. I guess you have not read my answer. The tests don’t make sense, it’s comparing completely different things that don’t relate. If you don’t understand this there was no learning.

1

If you use put() with an existing key, it will be overwritten. The map doesn’t have duplicate keys. You use replace to overwrite and put to add, but put does both.

  • Yes that I learned, but I wanted to know about the performance that changes... as a suggestion I will do the tests below!

  • Is there a reason to give 2 answers?

0

Take this simple test:

public static HashMap<String, String> Lista = new HashMap<>();

private static void methodTeste1(String teste, String outra) {
    for (int i = 0; i < 100000; i++) {
        if (Lista.size() > 0) {
            Lista.replace(teste, outra);
        } else {
            Lista.put(teste, outra);
        }
    }
}

private static void methodTeste2(String teste, String outra) {
    for (int i = 0; i < 100000; i++) {
        Lista.put(teste, outra);
    }

}

public static void main(String[] args) {
    long inicio, fim;

    inicio = System.currentTimeMillis();
    methodTeste1("antonio", "antonio");
    fim = System.currentTimeMillis();
    System.out.println("Replace: " + (fim-inicio)  + " ms");


    inicio = System.currentTimeMillis();
    methodTeste2("antonio", "antonio");
    fim = System.currentTimeMillis();
    System.out.println("Put: " + (fim-inicio) + " ms");
}
  • Take a look at my answer.

  • We responded together.

  • Is that your answer tests thing complements different, no matter which is faster, they do not give the same result.

  • What I have done is to help test him. Just so he can draw his conclusions based on what he wants to test. Everything is valid.

  • I made some modifications I put in to check if Lista.contains("antonio") and I also did other tests and as expected . replace was slower than . put in all 10 tests... of course the variations in some cases it took 1ms longer in others it took 10ms longer... but on a large scale this can end up turning SECONDS... I believe there is no need to use a check and use replace in my case, It’s better to use. direct put.

  • I only use put() in all these cases.

Show 1 more comment

0


After several tests I came to a conclusion: The .replace It should only be used when you’re sure the KEY already exists. If you are not sure of the existence of KEY (like my case) is more advantageous the use of . put right.

In the test where the existence of KEY was right and there was no need for checks on the .replace won easily:

public static HashMap<String, String> Lista = new HashMap<>();

private static void methodTeste1(String teste, String outra) {
    for (int i = 0; i < 100000; i++) {
        Lista.replace(teste, outra);    
    }
}

private static void methodTeste2(String teste, String outra) {
    for (int i = 0; i < 100000; i++) {
        Lista.put(teste, outra);
    }
}

public static void main(String[] args) {
    long inicio, fim;
    Lista.put("antonio", "antonio");

    inicio = System.currentTimeMillis();
    methodTeste1("antonio", "antonio");
    fim = System.currentTimeMillis();
    System.out.println("Replace: " + (fim-inicio)  + " ms");

    inicio = System.currentTimeMillis();
    methodTeste2("antonio", "antonio");
    fim = System.currentTimeMillis();
    System.out.println("Put: " + (fim-inicio) + " ms");
}

In the test where the existence of KEY was not certain and we were obliged to make checks the .put achieved a significantly higher performance:

public static HashMap<String, String> Lista = new HashMap<>();

private static void methodTeste1(String teste, String outra) {
    for (int i = 0; i < 100000; i++) {
        if (Lista.containsKey("antonio")) {
            Lista.replace(teste, outra);
        } else {
            Lista.put(teste, outra);
        }
    }
}

private static void methodTeste2(String teste, String outra) {
    for (int i = 0; i < 100000; i++) {
        Lista.put(teste, outra);
    }

}

public static void main(String[] args) {
    long inicio, fim;

    inicio = System.currentTimeMillis();
    methodTeste1("antonio", "antonio");
    fim = System.currentTimeMillis();
    System.out.println("Replace: " + (fim-inicio)  + " ms");

    inicio = System.currentTimeMillis();
    methodTeste2("antonio", "antonio");
    fim = System.currentTimeMillis();
    System.out.println("Put: " + (fim-inicio) + " ms");
}

Completion: .replace has greater performance than .put but everything will depend on the situation.

  • 2

    No, it’s the opposite of this.

  • ??????? I don’t understand

  • read my answer again, now carefully. I blacked out important things. The whole question is already wrong, so the conclusion can only be wrong. The comparison is being made between oranges and bananas. In my answer I put the equivalence of codes. When you test codes that produce different results you cannot look at the performance. The first code tests different things, but in the right way, the second tests different things and the wrong way.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.