StringJoiner vs StringBuffer vs Collectors.Joining() Performance Test

In this article we are sharing the program to identify which is the best performance provider out of StringJoiner, StringBuffer, StringBuilder and Collectors.joining() while joining/appending String.

import java.util.ArrayList;
import java.util.List;
import java.util.StringJoiner;
import java.util.stream.Collectors;
public class PerformanceTest {
	public static void main(String[] args) {
		List<String> l = new ArrayList<>();
		for(int i=0;i<1000;i++) {
			l.add("12345"+i);
		}
		long start = System.currentTimeMillis();
		usingStringJoiner(l);
		long middle = System.currentTimeMillis();
		System.out.println("Time taken by StringJoiner : "+(middle - start));
		usingStringBuffer(l);
		long end = System.currentTimeMillis();
		System.out.println("Time taken by StringBuffer : "+(end-middle));
		usingCollectors(l);
		long end1 = System.currentTimeMillis();
		System.out.println("Time taken by Collectors.joining() : "+(end1 - end));
		usingStringBuilder(l);
		System.out.println("Time taken by StringBuilder : "+(System.currentTimeMillis() - end1));
	}
	
	private static void usingStringJoiner(List<String> list) {
		StringJoiner sj = new StringJoiner("|");
		list.stream().filter(code -> code != null).forEach(code -> sj.add(code));
		String s = sj.toString();
		System.out.println(s);
	}
	
	private static void usingStringBuffer(List<String> list) {
		StringBuffer buf = new StringBuffer();
		list.stream().forEach(code -> buf.append(code).append("|"));
		String output = buf.toString();
		if (output.endsWith("|")) {
			output = output.substring(0, output.length() - 1);
		}
		System.out.println(output);
	}
	
	private static void usingCollectors(List<String> list) {
		String str = list.stream().collect(Collectors.joining("|"));
		System.out.println(str);
	}
	
	private static void usingStringBuilder(List<String> list) {
		StringBuilder builder = new StringBuilder();
		list.stream().forEach(code -> builder.append(code).append("|"));
		String output = builder.toString();
		if (output.endsWith("|")) {
			output = output.substring(0, output.length() - 1);
		}
		System.out.println(output);
	}
}

Time taken by StringJoiner : 49
Time taken by StringBuffer : 2
Time taken by Collectors.joining() : 4
Time taken by StringBuilder : 3

If you observe the above statistics of StringJoiner and Collectors.joining(), StringJoiners are taking 49 milliseconds to complete the task where Collectors.joining() is taking only 4 milliseconds which is 45 milliseconds lesser. Here one point I would like to bring to your notice is, StringJoiner is used in the implementation of joining() in Collections. But, when I use StringJoiner externally, it is taking more time than how joining() performing.

public static Collector<CharSequence, ?, String> joining(
CharSequence delimiter, CharSequence prefix, CharSequence suffix) {
    return new CollectorImpl<>(
            () -> new StringJoiner(delimiter, prefix, suffix),
            StringJoiner::add, StringJoiner::merge,
            StringJoiner::toString, CH_NOID);
}

StringJoiner internally uses StringBuilder to store value.

/*
 * StringBuilder value -- at any time, the characters constructed from the
 * prefix, the added element separated by the delimiter, but without the
 * suffix, so that we can more easily add elements without having to jigger
 * the suffix each time.
 */
private StringBuilder value;

/* preparing StringBuiler object in StringJoiner */
private StringBuilder prepareBuilder() {
  if (value != null) {
    value.append(delimiter);
  } else {
    value = new StringBuilder().append(prefix);
  }
  return value;
}

StringBuilder has been used across all the methods of StringJoiner to perform various operations. There is one more option of using StringUtils.join() method to perform similar operation. I would like to suggest to use StringBuffer than StringUtils because it internally uses the StringBuffer only to store value.

Recursive Sub-search In Splunk

Many a times we find ourselves in a situation where we have to search the logs based on a unique id recursively, and to make things that little bit harder we would have to initially find a candidate line in the logs, then cut the line to get a unique id and then search logs with this unique id. In our good old days of shell  scripts we could have written something like…

If the log we are supposed to search looks something like the line below.

Paragraph 1

2019-12-19 09:20:33.414920 ‘SVRREQ’ ‘4753065a-221f-11ea-b0b5-0a0634110000’ ‘{“ProductId”:”834682″,”ProductNo”:”123543673433212348567″,”Remarks”:”Is This fancy?”}’

2019-12-19 09:20:33.414930 ‘SVRRES’ ‘4753065a-221f-11ea-b0b5-0a0634110000’ ‘{“Response”:”Yes Indeed!”}’

we can write a simple script first to get the unique id and then to search it in the log again, which would look something like.

grep 834682 yourfile.log | cut -d “” -f4 | while read i ; do grep $i yourfile.log ; done;

The first grep would output only the request, which has a unique id and the only way of finding the response is through this unique id.

grep 834682 yourfile.log | cut -d “‘” -f4  Would Output  4753065a-221f-11ea-b0b5-0a0634110000

and

while read i ; do grep $i yourfile.log ; done;  Would Output both the lines displayed in Paragraph 1. 

Writing this script for one single search seems an overkill, but what if you wanted to extract all the responses for which the request had the text “Fancy”? you could simply write

grep -i  fancy yourlogfile.log | cut -d “” -f4 | while read i ; do grep $i yourfile.log  | grep SVRRES ; done;

Now we start to see the benefit of this script. What if we had to the similar thing in splunk? our task can be divided into three parts.

  1. Defining a Splunk Variable.
  2. Running  Inner Query.
  3. Running Outer Query.

Defining a splunk variable is pretty straight forward, can be done by following steps described in the link below.

https://docs.splunk.com/Documentation/Splunk/8.0.1/Knowledge/FXSelectSamplestep

Once done we can use our  new variable by using the search command “fields”

so..

  1. Defining a Splunk Variable.
    1. Based on the link provided above, lets assume we have named it TransactionId( Field names are case sensitive)
  2. Running  Inner Query.
    1. [search index = yourindex  source = “yourlogfile.log” fancy  | fields TransactionId]
  3. Running Outer Query.
    1. index = yourindex  source = “yourlogfile.log”  <Inner Query Result goes here> SVRRES

If we put everything together the executable query would look like below.

index = yourindex  source = “yourlogfile.log” [search index = yourindex  source = “yourlogfile.log” fancy  | fields TransactionId ] SVRRES

this splunk search would first pickup all the lines which have the word “fancy” in them and then only output the field TransactionId to be used by the outer search as a string of OR’s , From Outer query’s point of view its the below query running, Example.

index = yourindex  source = “yourlogfile.log” [“4753065a-221f-11ea-b0b5-0a0634110000” OR “4753065a-221f-11ea-b0b5-0a0634110001” OR “4753065a-221f-11ea-b0b5-0a0634110000” ] SVRRES

Bear in mind that this method has a limit of 10500 in the sub-search results, and there are better approaches such as using lookup files or the join command, when the amount of data to be correlated is huge. Most of the time the query explained in this post would fit our requirement.

Laptop RAM upgrade issue

The objective of current post to share the problem which I have faced after upgrading RAM from 8 GB to 16 GB in my Lenovo laptop. I recently upgraded my system RAM size from 8 GB to 16 GB and started facing lot’s of troubles even it has been upgraded with the help of authorized laptop service professionals.

Problems:

  1. System is showing the blur lines on blue screen within few minutes of after starting the laptop.
  2. System not at all booting (not even showing the vendor name while starting)

Blur lines on blue screen:

As shown in the previous video, that’s how my laptop was troubling me after updating the RAM size from 8 GB to 16 GB. Since I can’t take any action on that screen, I did force shutdown of my laptop and starting facing the other problem of not even booting after that.

System not booting:

After getting the problem of showing in previous video, I did force/hard shutdown of my laptop, then system is stopped booting at all. It’s not even showing the vendor name.

Solution:

If you are facing exactly similar problem with your laptop, I would like to suggest you to interchange each RAM into each other slots. This is the solution finally solved my problem. If still you have the same problem, follow the below steps.

Further Analysis:

  1. Keep only your old RAM and remove the new RAM which you placed recently.
  2. Still there is a chance of getting the same problem with your old RAM if you didn’t place into correct slot. If you get the same problem, change into another RAM slot available(Any laptop, minimum should have 2 slots). So now your system is as it is like before RAM upgrade and it should work like previously.
  3. Now, insert new RAM into another slot available. It should work properly.

Note: If still you are facing the problem, the RAM which you placed newly is not compatible for your system.