Using currentTimeMillis() to compare concat and append - java

String conSingles = ""; //one to cong. single chars to
String appendSingles = "";
//Testing one char conc. and append
long before = System.currentTimeMillis(); //static method so no new
for(int i = 0; i <10; i++) {
for (int j = 0; j <70000; j++) {
conSingles += "j";
}
conSingles=""; //Clear string
}
long after = System.currentTimeMillis();
long before2 = System.currentTimeMillis(); //static method so no new
for(int i = 0; i <10; i++) {
StringBuilder appSingles = new StringBuilder(); //one to append single chars to
for (int j = 0; j < 75000000; j++) {
appSingles.append("j");
}
appendSingles = appSingles.toString();
appendSingles = "";
}
long after2 = System.currentTimeMillis();
long total = (after-before)/10;
long total2 = (after2-before2)/10;
I am comparing how many one char strings I can put together in 1000 msec with String concat vs StringBuilder append. I am close to 1000 msec when I run the loop once, but when I do it ten times, for average, I always get around 3-400 msec in average per round. What is it in my method that makes round of one so slow compared to 10 rounds?

Related

Can someone tell me what am I doing wrong here in my Java code when trying to find count of substrings in given string according to given queries?

There are queries in array findStr, and for each query, I am given a target suffix. I have to determine the count of strings in the array strr that have the suffix as the target suffix. The queries are given as an array of strings findStr.
Example
Assumptions
strr = ["asdfc", "asfc", "vdsfc", "trgfds", "egregds", "tertdfc", "rtyergds"]
findStr = ["dfc", "fc", "ds"]
Approach:
In the 1st Query, the required suffix is "dfc". The strings that have this suffix are [asdfc, tertdfc]. Hence, the count is 2.
In 2nd query, the required suffix is "fc". The strings that have this suffix are [asdfc, asfc, vdsfc, tertdfc]. Hence, the count is 4.
In 3rd query, the required suffix is "ds". The strings that have this suffix are [trgfds, egregds, rtyergds]. Hence, the count is 3.
Hence the output is [2,4,3].
But When I'm trying to do this using my code I'm getting wrong output [2,6,10]. Can anyone tell me what I'm doing wrong here ?
class FindCount {
public static void main(String[] args) {
String[] strr = new String[]{"asdfc", "asfc", "vdsfc", "trgfds", "egregds", "tertdfc", "rtyergds"};
String[] findStr = new String[]{"dfc", "fc", "ds"};
int count = 0;
int result[] = new int[findStr.length];
for (int i = 0; i < findStr.length; i++) {
for (int j = 0; j < strr.length; j++) {
count += findCount(strr[j], findStr[i]);
}
result[i] = count;
}
for(int l: result)
System.out.println(l);
}
static int findCount(String str, String findStr) {
int lastIndex = 0;
int count = 0;
while (lastIndex != -1) {
lastIndex = str.indexOf(findStr, lastIndex);
if (lastIndex != -1) {
count++;
lastIndex += findStr.length();
}
}
return count;
}
}
You should make the count variable local to the first loop so that the count starts at 0 for each suffix.
Use String#endsWith to check if a string ends with a particular suffix, and increment the count by 1 each time this is true.
for (int i = 0; i < findStr.length; i++) {
int count = 0;
for(String str: strr)
if(str.endsWith(findStr[i])) ++count;
result[i] = count;
}
for(int l: result)
System.out.println(l);
You need to reset count to 0 at the beginning of each iteration.
Otherwise it will count the occurrences of the previous substrings as well.
for (int i = 0; i < findStr.length; i++) {
count = 0;
for (int j = 0; j < strr.length; j++) {
count += findCount(strr[j], findStr[i]);
}
result[i] = count;
}

How to populate 2D boolean array between two coordinates?

I'm trying to create a daily time block for my calendar app. I have an idea of creating a 2D array representing all the minute in a day:
final int hour = 24, min = 60;
boolean dayBlock[][] = new boolean [hour][min];
//Initialize the array. true = available, false =
busy.
for (int j = 0; j < 24; j++) {
for (int i = 0; i < 60; i++) {
dayBlock[j][i] = true;
}
}
However, I'm struggling how to write an algorithm to populate from (startHour, startMin) to (endHour, endMin) for an event with precision.
Since I'm doing this for multiple events, I can't just go over and then backtrack since it will mess up the previous event time-block.
To mark something ranging from (startHour, startMin) to (endHour, endMin)
// mark false for the remaining minutes in first hour
for (int i = startMin; i < 60; i++) {
dayBlock[startHour][i] = false;
}
// mark false for every minute after first hour and before last hour
for (int j = startHour+1; j < endHour; j++) {
for (int i = 0; i < 60; i++) {
dayBlock[j][i] = false;
}
}
// mark false for the remaining minutes in last hour
for (int i = 0; i < endMin; i++) {
dayBlock[endHour][i] = false;
}
I think you should probably rethink your idea of using a 2D array.
You are trying to represent time, which is naturally not two dimensional, but one dimensional.
Instead of a 2D array, why not use simple 1D array like this:
boolean dayBlock[] = new boolean[hour * minute];
To calculate where a given time is represented in the array, just use:
int start = theHour * 60 + theMinute;
Another option could be to think of an imaginary index for your 2d array from 0 to 1440 (24*60), which enables you to make something like below for your params (startHour, startMin) (endHour, endMin):
int startHour = 6;
int startMin = 15;
int endHour = 8;
int endMin = 0;
int strat = startHour * 60 + startMin;
int end = endHour * 60 + endMin;
for(int i = strat; i <= end; i++){
dayBlock[i/60][i%60] = false;
}
// Take input from user for start and end hour and start and end minuted and validate the boundary values.
int startHour,endHour,startMinute,endMinute;
for (int j = startHour; j <= endHour; j++) {
int i = 0;
if(j==startHour){
i= startMinute;
}
for (; i < 60; i++) {
if(j==endHour && i> endMinute) {
break;
}
dayBlock[j][i] = ;// if busy set false or true if available.
}
}

Null/Object and Null/Null comparison efficiency

This question lead me to do some testing:
public class Stack
{
public static void main(String[] args)
{
Object obj0 = null;
Object obj1 = new Object();
long start;
long end;
double difference;
double differenceAvg = 0;
for (int j = 0; j < 100; j++)
{
start = System.nanoTime();
for (int i = 0; i < 1000000000; i++)
if (obj0 == null);
end = System.nanoTime();
difference = end - start;
differenceAvg +=difference;
}
System.out.println(differenceAvg/100);
differenceAvg = 0;
for (int j = 0; j < 100; j++)
{
start = System.nanoTime();
for (int i = 0; i < 1000000000; i++)
if (null == obj0);
end = System.nanoTime();
difference = end - start;
differenceAvg +=difference;
}
System.out.println(differenceAvg/100);
differenceAvg = 0;
for (int j = 0; j < 100; j++)
{
start = System.nanoTime();
for (int i = 0; i < 1000000000; i++)
if (obj1 == null);
end = System.nanoTime();
difference = end - start;
differenceAvg +=difference;
}
System.out.println(differenceAvg/100);
differenceAvg = 0;
for (int j = 0; j < 100; j++)
{
start = System.nanoTime();
for (int i = 0; i < 1000000000; i++)
if (null == obj1);
end = System.nanoTime();
difference = end - start;
differenceAvg +=difference;
}
System.out.println(differenceAvg/100);
}
}
Tangential to the other post, it's interesting to note how much faster the comparison is when the Object that we're comparing is initialized. The first two numbers in each output are when the Object was null and the latter two numbers are when the Object was initialized. I ran 21 additional executions of the program, in all 30 executions, the comparison was much faster when the Object was initialized. What's going on here?
If you move last two loops to the beginning you will get the same results, so comparisons are irrelevant.
It's all about JIT compiler warm-up. During the first 2 loops java starts with interpreting bytecode. After some iterations, it determines that code path is "hot", so it compiles it to machine code and removes the loops that have no effect, so you are basically measuring System.nanotime and double arithmetic.
I'm not really sure why two loops are slow. I think that after it finds two hot paths it decides to optimize entire method.

subString combined with the practices of the for loop

I get a long list of strings from the server
AS= String1 ~ String2 ~ String3 ~
Can be determined.
"~"Represents the end of each data.
I know that the word limit for each String of up to 22
But I do not know his actual length.
So I use this code to determine the value of each String
//////////////////////////Use of substring Get every character
String T1=AS.substring(0,1);
String T2=AS.substring(1,2);
.
.
.
String T22=AS.substring(21,22);
if (T2.equals("~")) {
DATA=T1;
}
if (T3.equals("~")) {
DATA=T1+T2;
}
//Confirm T3 "~" Get DATA = T2 + T1
String LG=LG+DATA.length()+1;
//The second document must be added to the number of words in the document "~"
String TT1=AS.substring(0+LG,1+LG);
Determine string of 100
Repeat 100 times
I have manufactured more than 8,000 lines of code
There is no easier way to reach my request?
Just a little bit to help you out.
String[] TKG = new String[GUY.length];
for (int i = 0; i < GUY.length - 1; i++)
{
TKG[i] = GUY.substring(i, i+1);
}
and then
StringBuilder DETA5 = new StringBuilder();
for (int i = 1; i < TKG.length; i++)
{
if (TKG[i].equals("~"))
{
for (int x = 0; x < i; x++)
{
DETA5.append(TKG[x]);
}
}
}
int D = D + DETA5.length();
String[] TKC = new String[6];
for (int i = 0; i < 6; i++)
{
TKC[i] = GUY.substring(i+D1, i + 1 + D1);
}
StringBuilder DETA_1_1 = new StringBuilder();
for (int i = 1; i < TKC.length; i++)
{
if (TKC[i].equals("~"))
{
for (int x = 0; x < i; x++)
{
DETA_1_1.append(TKC[x]);
}
}
}
Good Luck!
It looks almost as if a simple String#split(...) will do the trick for you. Have you tried something along the lines of
String[] tokens = guy.split("~");
Perhaps after a little cleaning up of the edge Strings, you'll have what you want.

decompose a string into array of int

What is the shortest and most efficient way to decompose a string array into an array of int's if the string looks like:
4 1 4 2 3
5 1 4 2 -1 6
The way I have it now is to use String split method and iterate the String array into int's.. Is there a better way than this?
That's fine - I'd just call split(" ") and then use Integer.parseInt() on the resulting elements.
If you could potentially have more than one space between the ints, you'll need something like split("\\s+") for it to work properly.
If that's what you're doing, I don't think there's a better way!
EDIT: Perhaps I should qualify the term better - I mean that for all practical purposes, unless you're really hitting performance critical issues, I'd stick with this method since it's clean and easy to understand what's going on!
Using split() consumes more space [and time], as new String objects are created, but it is far more elegant [and simple] then any other way.
unless performance is very critical, I'd stick with this way.
Algorithm 3times faster than the split method! :)
Just for the fun of it I have made an algorithm that is far faster than the split method.
Maybe nothing you should use as I would say split is cleaner and cleaner is far more important than speed. Also the Donald Knuth quote of premature optimizations are the root cause of all evil.
Output
1189ms // My algorithm first loop
3305ms // Split algorithm runtime first loop
1173ms // My algorithm second loop
3305ms // Split algorithm second loop
The code
import java.util.ArrayList;
class FarmorsOptimized {
#SuppressWarnings({ "rawtypes", "unchecked" })
private static ArrayList getFarmors(String s) {
ArrayList intArr = new ArrayList();
int stopvalue = s.length() ;
for (int i = 0; i < stopvalue;) {
int negativ = 0;
if (s.charAt(i) == '-') {
negativ = 1;
}
intArr.add(Integer.parseInt(s.substring(i, i+1+negativ)));
i+=2+negativ;
}
return intArr;
}
#SuppressWarnings({ "rawtypes", "unchecked" })
private static ArrayList getSplits(String s) {
ArrayList intArr = new ArrayList();
for(String str : s.split(" ")){
intArr.add(Integer.parseInt(str));
}
return intArr;
}
public static void main(String[] args) {
String s = "1 2 4 -6 7 1 2 4 -6 7 1 2 4 -6 7 1 2 4 -6 7 1 2 4 -6 7 1 2 4 -6 7 1 2 4 -6 7";
int times = 1000000;
//Just to init everything
for (int i = 0; i < times; i++) {
getFarmors(s);
getSplits(s);
}
long starttime = System.currentTimeMillis();
for (int i = 0; i < times; i++) {
getFarmors(s);
}
System.out.println(System.currentTimeMillis() - starttime);
starttime = System.currentTimeMillis();
for (int i = 0; i < times; i++) {
getSplits(s);
}
System.out.println(System.currentTimeMillis() - starttime);
starttime = System.currentTimeMillis();
for (int i = 0; i < times; i++) {
getFarmors(s);
}
System.out.println(System.currentTimeMillis() - starttime);
starttime = System.currentTimeMillis();
for (int i = 0; i < times; i++) {
getSplits(s);
}
System.out.println(System.currentTimeMillis() - starttime);
}
Answer to comment discussion.
This answer works for all ints.
It's significantly faster than the split.
1295ms my
2193ms split
1155ms my
1889ms split
code
import java.util.ArrayList;
class FarmorsOptimized {
public static void main(String[] args) {
String s = "32324 -324 873249 -8544876 -74093 -3243274 4325 643286 92325 -21376218 -213 2132531 2314 1 2";
int times = 1000000;
long starttime = System.currentTimeMillis();
for (int i = 0; i < times; i++) {
getFarmors(s);
}
System.out.println(System.currentTimeMillis() - starttime);
starttime = System.currentTimeMillis();
for (int i = 0; i < times; i++) {
getSplits(s);
}
System.out.println(System.currentTimeMillis() - starttime);
starttime = System.currentTimeMillis();
for (int i = 0; i < times; i++) {
getFarmors(s);
}
System.out.println(System.currentTimeMillis() - starttime);
starttime = System.currentTimeMillis();
for (int i = 0; i < times; i++) {
getSplits(s);
}
System.out.println(System.currentTimeMillis() - starttime);
}
#SuppressWarnings({ "rawtypes", "unchecked" })
private static ArrayList getFarmors(String s) {
ArrayList intArr = new ArrayList();
int stopvalue = s.length();
for (int i = 0; i < stopvalue;) {
int j = 0;
while (true) {
if ((i + j) == stopvalue || s.charAt(i + j) == ' ') {
break;
}
j++;
}
intArr.add(Integer.parseInt(s.substring(i, i + j)));
i += j + 1;
}
return intArr;
}
#SuppressWarnings({ "rawtypes", "unchecked" })
private static ArrayList getSplits(String s) {
ArrayList intArr = new ArrayList();
String[] strArr = s.split(" ");
for(int i = 0; i < strArr.length ; i++){
intArr.add(Integer.parseInt(strArr[i]));
}
return intArr;
}
}

Categories

Resources