0

I made a little code to use as an example:

public class Main {

    public static void main(String[] args) {
        String hugeString = "a,a,a,a";

        splitOutside(hugeString.split(","));
        splitInside(hugeString);

    }

    private static void splitInside(String string) {
        String splitData[] = string.split(",");
        for (int i = 0; i < splitData.length; i++){
            System.out.print(splitData[i]);
        }
       System.out.println("");
    }

    public static void splitOutside(String[] splitData) {
        for (int i = 0; i < splitData.length; i++){
            System.out.print(splitData[i]);
        }
        System.out.println("");
        }
}

I have two different functions, splitOutside and splitInside, in this case.

Is any of these better than the other in terms of memory usage? Will splitting the string inside the function help the Garbage collector?

As I said, this is just a tiny example, the real code has huge strings which need to be splitted, and it receives many of these strins each second. So the difference might be noticeable in the long run (it's a software that needs to be ON for periods of over 100 hours).

Will it make a difference using one method or the other?

Update:

This question is not the same as java how expensive is a method call.

I am not asking if the call to a method is expensive, I am asking if the call to String.split(); inside or outside of the function makes any difference.

Update 2:

What if I have this? Will it be different?

while ((hugeString = br.readLine()) != null) {
    splitOutside(hugeString.split(","));
    splitInside(hugeString);
}

I forgot to mention I am constantly reading from outside the JVM in an (almost) endless loop (the split will happen 2-10 times a second).

Community
  • 1
  • 1
Mayuso
  • 1,291
  • 4
  • 19
  • 41
  • unless you are going to split the data multiple times, I can see no difference – Scary Wombat Sep 28 '16 at 08:39
  • I do it 2-10 times a second (With different strings) for periods of over 100 hours. 2-10 because it depends on the input, of other softwares. – Mayuso Sep 28 '16 at 08:40
  • Possible duplicate of [java how expensive is a method call](http://stackoverflow.com/questions/6495030/java-how-expensive-is-a-method-call) – xenteros Sep 28 '16 at 08:41
  • References (copies of references actually) are passed in both instances (which is always the case in Java with objects), so you really shouldn't worry about this. – dsp_user Sep 28 '16 at 08:41
  • Updated explaining why it is not a duplicate. We are asking different things. – Mayuso Sep 28 '16 at 08:46
  • It is the same amount of work – Scary Wombat Sep 28 '16 at 08:49

2 Answers2

2

There is no difference. The result of hugeString.split(",") is only reachable until the method using it completes, since this is the only part of the code receiving the reference. The same happens in the splitInside method.

To decrease the footprint it would be far better not to keep the complete array in memory, but find the substrings one after the other:

private static final Pattern PATTERN = Pattern.compile("[^,]*");

private static void splitInside(String string) {
    Matcher matcher = PATTERN.matcher(string);
    while (matcher.find()) {
        System.out.print(matcher.group());
    }
    System.out.println();
}

Note that here there is only a reference to a single of the substrings at a time instead of all of them at once. (You add some overhead for the Pattern/Matcher though.)

fabian
  • 80,457
  • 12
  • 86
  • 114
  • I updated. Check update 2 please. I execute it in a loop, will there be a difference in when the Garbage collector can release that memory? – Mayuso Sep 28 '16 at 08:57
  • @Mayuso: Doesn't make a difference... And why would it??? The explanation still applies. – fabian Sep 28 '16 at 09:01
  • I just thought the outside function (The one containintg the while loop, in this case, the main function) would keep the data of hugeString forever (You know, because ithat function never ends, it always stays in the while loop). Meanwhile spliting the string inside the function would free that memory as soon as `splitInside(hugeString)` ends. In my mind this made sense, as you can see I am not an expert, and I guess I was wrong :) Thank you for the help. – Mayuso Sep 28 '16 at 09:03
  • @Mayuso: You still retain a reference to the string outside of the method. The object that could be dropped is the array. Reading the data like this makes a line available for garbage collection as soon as a new line is read though... – fabian Sep 28 '16 at 09:06
  • Thank you for explainin everything, you helped me a lot :) – Mayuso Sep 28 '16 at 09:45
  • Assuming `hugeString` does not refer to a compile-time constant (unlike the question’s example code), the string can be freed right after the `split` operation, as it is not touched anymore. The idea of garbage collection being prevented by the mere existence of a reference held in a local variable is tempting, but provenly wrong. In fact, the string might even get collected, before `split` returns, once it’s not needed anymore. See [“finalize() called on strongly reachable object in Java 8”](http://stackoverflow.com/questions/26642153/)… – Holger Sep 30 '16 at 10:03
0

There is no difference, as the same operations will be applied anyway. You could even try to measure the time taken, but to be honest this is meaningless and you shouldn't worry about it at all, what you should worry about is your design and whether or not it is appropriate to pass a full String or a split String.

SamTebbs33
  • 5,507
  • 3
  • 22
  • 44
  • I updated. Check update 2 please. I execute it in a loop, will there be a difference in when the Garbage collector can release that memory? – Mayuso Sep 28 '16 at 08:58