What is the preferred way to deal with two-dimensional arrays? - java

I'm not good with java conventions and best practices.
I need two-dimensional buffer for some big calculation involving dynamic programming and doubt if I should use one-dimensional array and map two coordinates to single, or use array of arrays and chained access by indexes.
In C I would prefer the first way, but Java is not a C and may have extra specifics that matter.

If you need top speed, definitely use a single array (one-dimensional) and map your indices as appropriate. As I see in the thread linked to in a comment below your question, people seem to disregard the ill effects of 2d-arrays on CPU cache lines and emphasize only the number of memory lookups.
There is one consideration to take: if your inner arrays are large enough (1K or more, say), then the speed advantage starts fading away. If the inner arrays is smallish (like 10-50), then the difference should be noticeable.
EDIT
As rightfully demanded, here's my jmh benchmark:
#OutputTimeUnit(TimeUnit.SECONDS)
public class ArrayAccess
{
static final int gapRowsize = 128, rowsize = 32, colsize = 10_000;
static final int[][] twod = new int[colsize][],
gap1 = new int[colsize][];
static final int[] oned = new int[colsize*rowsize];
static final Random r = new Random();
static {
for (int i = 0; i < colsize; i++) {
twod[i] = new int[rowsize];
gap1[i] = new int[gapRowsize];
}
for (int i = 0; i < rowsize*colsize; i++) oned[i] = r.nextInt();
for (int i = 0; i < colsize; i++)
for (int j = 0; j < rowsize; j++)
twod[i][j] = r.nextInt();
}
#GenerateMicroBenchmark
public int oned() {
int sum = 0;
for (int i = 0; i < rowsize*colsize; i++)
sum += oned[i];
return sum;
}
#GenerateMicroBenchmark
public int onedIndexed() {
int sum = 0;
for (int i = 0; i < colsize; i++)
for (int j = 0; j < rowsize; j++)
sum += oned[ind(i,j)];
return sum;
}
static int ind(int row, int col) { return rowsize*row+col; }
#GenerateMicroBenchmark
public int twod() {
int sum = 0;
for (int i = 0; i < colsize; i++)
for (int j = 0; j < rowsize; j++)
sum += twod[i][j];
return sum;
}
}
Note the gap array allocation: this simulates the worst-case scenario with fragmented heap.
I see more than 5-fold advantage at rowsize = 32 and a still quite noticeable (25%) advantage at 1024. I also find the advantage to highly depend on the gap size, with the shown 128 being the worst case for rowsize = 32 (both higher and lower values diminish the advantage), and 512 the worst case for rowsize = 1024.
rowsize = 32, gapRowsize = 128
Benchmark Mean Units
oned 8857.400 ops/sec
twod 1697.694 ops/sec
rowsize = 1024, gapRowsize = 512
Benchmark Mean Units
oned 147.192 ops/sec
twod 118.275 ops/sec

Related

how to find max value of the two-dimensional array in java using multithreading

I want to find the maximum value of the two-dimensional array. I found this value without using multithreading. How do I find the maximum value of the two-dimensional array using multithreading? I want to compare the speed of finding the maximum value of the array in different ways.
public class Search {
public int[][] fillMatrix(int matrix[][]) {
for (int i = 0; i < matrix.length; i++){
for (int j = 0; j < matrix[i].length; j++){
matrix[i][j] = (int)(Math.random() * 1000);
}
}
return matrix;
}
public int searchMaxValue(int[][] matrix, int row, int column) {
int max = matrix[0][0];
for (int a = 0; a < row; a++) {
for (int b = 0; b < column; b++) {
try {
Thread.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
if (matrix[a][b] > max) {
max = matrix[a][b];
}
}
}
return max;
}
public static void main(String[] args) {
Search search = new Search();
int[][] matrix = new int[4][100];
search.fillMatrix(matrix);
long start = System.currentTimeMillis();
int max = search.searchMaxValue(matrix, 4, 100);
long end = System.currentTimeMillis();
System.out.println("Max value is " + max);
System.out.println("Time for execution: " + (end - start));
}
}
Here is the outline how you would go about implementing this. I am not providing code intentionally, so that you can have the joy of implementing it yourself.
create a method to findmax out of an array lets call it findMax(int[]
input)
for each sub array in 2D array (can be accessed using matrix[i])
start a thread to findMax(matrix[i]) (hint: use ExecutorService)
in the thread, once max is found, fill it in to ith position
of a one dimensional array called results in the thread, indicate
its completion(hint: use CountDownLatch)
In the main thread, wait till all threads finish ( hint: use
CountDownLatch) Now call findMax(results) and you have the
maxiumum from matrix.
Considerations: Do we need to fork as many threads as the rows in matrix? So do we use a FixedThreadPool with number of rows ?
The simplest way would be to start a thread to calculate the maximum in each of the four rows in the matrix, have the main thread join all of these row threads and calculate the maximum of the four row maxima. You will likely need a much larger array to be able to see the time difference, though. Don't neglect the necessary synchronization.
If as I suspect you are looking for code, you should make an attempt at the solution and run it, then repost or elaborate this post with the problems you run into.
Here is how to do it in java 8:
int[][] values = fillMatrix(new int[1000][1000]);
OptionalInt max = Arrays.stream(values)
.parallel()
.flatMapToInt(Arrays::stream)
.parallel()
.max();
But frankly speaking, I'm not sure that for such simple computation it makes sense to use several threads, indeed creating and orchestrating threads has a price which seems to be too high in this case.
Response Update
As it is your homework, I provide an answer without any comments on purpose in order to ensure that you will at least think about how it works, but the main idea is to provide chunk of data to each thread to avoid collisions as next:
int[][] matrix = fillMatrix(new int[100][100]);
int totalThreads = 10;
int[] results = new int[totalThreads];
int chunkSize = matrix.length / totalThreads;
CountDownLatch end = new CountDownLatch(totalThreads);
for (int i = 0; i < totalThreads; i++) {
int threadIndex = i;
new Thread(
() -> {
int max = -1;
int startIndex = threadIndex * chunkSize;
for (int j = startIndex; j < startIndex + chunkSize && j < matrix.length; j++) {
for (int k = 0; k < matrix[j].length; k++) {
if (max == -1 || max < matrix[j][k]) {
max = matrix[j][k];
}
}
}
results[threadIndex] = max;
end.countDown();
}
).start();
}
end.await();
int max = results[0];
for (int k = 1; k < results.length; k++) {
if (max < results[k]) {
max = results[k];
}
}
System.out.printf("Max found %d%n", max);

Beginner Looking for Guidance on Methods

I am trying to complete a project where we have to take a set of data of random numbers between 0 and 364 and see what percentage of the runs (the method takes the number of items in the data set and the number of runs) have a duplicate number in them.
Below is what I have so far, but I am really struggling to figure out how to do this as I keep getting errors:
public double calculate(int size, int count) {
double percentage;
int matches = 0;
int check;
int i = 0;
int add = 0;
Random rnd = new Random();
List<Integer> birthdays = new ArrayList<>();
for (int k = 1; k <= count; k++){
rnd.setSeed(k);
do{
add = rnd.nextInt(365);
birthdays.add(add);
i++;
}while (i < size-1);
//birthdays.add(rnd.nextInt());
for (int j = 0; j <= size-1; j++) {
check = birthdays.get(j);
if (birthdays.indexOf(check) != birthdays.lastIndexOf(check)) {
matches++;
j = size;
}
}
}
percentage = (double)matches / count * 100;
//percentage = 8;
return percentage;
}
There are a couple of problems with your code here. One is the while loop directly after the first for loop that doesn't seem to be doing anything. It says:
while(i < size-1);
That might be giving you an error, but error you are talking about is probably from your second for loop. When you instantiate it you say:
for (int j = 0; j <= size-1; j++)
but then you say:
j = size;
since when you instantiate it you say j<=size-1 but then you set j=size it will give an error.

radix sort (java implementation) complexity

this is my first question so I hope I haven't broken any rules. I have finally just managed to write code for the Radix Sort algorithm but I am wondering if I have done it wrong. What makes me think that is that my algorithm looks of complexity O(n^3) but Radix Sort is notoriously a O(k.n) algorithm. Am I calculating the complexity of my algorithm wrong or did I just write really bad code?
private static void radixSort(int[] A){
ArrayList<Integer>[] bucket = new ArrayList[10];
int maxNumberOfDigits = 0;
for(int number : A){
if(numberOfDigitsIn(number) > maxNumberOfDigits) maxNumberOfDigits = numberOfDigitsIn(number);
}
for(int c=0; c<bucket.length; c++){
bucket[c] = new ArrayList<Integer>();
}
int i = 0;
int digit;
int j;
while(i < maxNumberOfDigits){
for(j = 0; j<A.length; j++){
digit = getDigit(A[j], i);
bucket[digit].add(A[j]);
}
int index = 0;
for(int z = 0; z<bucket.length; z++){
for (int k=0; k<bucket[z].size(); k++){
A[index] = bucket[z].get(k);
index += 1;
}
bucket[z].clear();
}
i += 1;
}
}
The methods getDigit() and numberOfDigitsIn() are of constant time.
for(int z = 0; z<bucket.length; z++){
for (int k=0; k<bucket[z].size(); k++){
The crucial thing here is that the sum total of all the bucket sizes will equal n, so these loops combined only take O(n). The loop over j takes O(n), and the while loop on i will run for maxNumberOfDigits iterations, and that number represents k in the O(kn) runtime you described. So the total is, in fact, O(kn).

What is the most efficient implementation of for loop for ArrayList?

I just recently finished an android project and I have done some extensive codes of ArrayList and doing looping stuffs on it. I have two sets example of loops here.
ArrayList<SomeObject> object = new ArrayList<SomeObject>();
for(int c=0;c<object.size();c++){
}
for(SomeObject obj: object){
}
I think the second one is good if you don't need the incrementing value and I think far more readable and neat than the first. But what in the two loops is ideal or efficient to use in terms speed, performance and memory usage?
As per suggestions from the Android Documentation the most efficient ways for making loop are:
public void one() {
int sum = 0;
Foo[] localArray = mArray;
int len = localArray.length;
for (int i = 0; i < len; ++i) {
sum += localArray[i].mSplat;
}
}
public void two() {
int sum = 0;
for (Foo a : mArray) {
sum += a.mSplat;
}
}
Please, note that these ways have same performance for devices with JIT. So, in cases then JIT is off (e.g. while debugging using Eclipse) You might observe different results (two() will be faster than one())
Update
I've checked ArrayLists also by using the following code:
final ArrayList<String> testArrayList = new ArrayList<String>(1000);
for (int i = 0; i < 1000; i++) {
testArrayList.add(String.valueOf(i<<2));
}
final TimingLogger timings = new TimingLogger("Loop", "ArrayLists");
timings.addSplit("start");
for (int loopCount = 0; loopCount < 1000; loopCount++) {
int sum = 0;
for (int i = 0; i < testArrayList.size(); i++) {
sum += Integer.valueOf(testArrayList.get(i));
}
}
timings.addSplit("zero()");
for (int loopCount = 0; loopCount < 1000; loopCount++) {
int sum = 0;
final int len = testArrayList.size();
for (int i = 0; i < len; i++) {
sum += Integer.valueOf(testArrayList.get(i));
}
}
timings.addSplit("one()");
for (int loopCount = 0; loopCount < 1000; loopCount++) {
int sum = 0;
for (String item : testArrayList) {
sum += Integer.valueOf(item);
}
}
timings.addSplit("two()");
timings.dumpToLog();
And obtained the following output (with JIT):
ArrayLists: begin
ArrayLists: 0 ms, start
ArrayLists: 2713 ms, zero()
ArrayLists: 1753 ms, one()
ArrayLists: 1922 ms, two()
ArrayLists: end, 6388 ms
So, we able to see, that variants one() and two() provides similar results, and these results are faster than zero() (so, results look similar to ones described in the documentation for arrays).

finding time and space complexity of the given java code

hi i need to find the time and space complexity of the program, pls help, if possible please suggest the optimization that can be performed,
.........................................................................................................................................................................................
public class Sol {
public int findMaxRectangleArea(int [][] as) {
if(as.length == 0)
return 0;
int[][] auxillary = new int[as.length][as[0].length];
for(int i = 0; i < as.length; ++i) {
for(int j = 0; j < as[i].length; ++j) {
auxillary[i][j] = Character.getNumericValue(as[i][j]);
}
}
for(int i = 1; i < auxillary.length; ++i) {
for(int j = 0; j < auxillary[i].length; ++j) {
if(auxillary[i][j] == 1)
auxillary[i][j] = auxillary[i-1][j] + 1;
}
}
int max = 0;
for(int i = 0; i < auxillary.length; ++i) {
max = Math.max(max, largestRectangleArea(auxillary[i]));
}
return max;
}
private int largestRectangleArea(int[] height) {
Stack<Integer> stack =
new Stack<Integer>();
int max = 0;
int i = 0;
while(i < height.length) {
if(stack.isEmpty() ||
height[i] >= stack.peek()) {
stack.push(height[i]);
i++;
}
else {
int count = 0;
while(!stack.isEmpty() &&
stack.peek() > height[i]) {
count++;
int top = stack.pop();
max = Math.max(max, top * count);
}
for(int j = 0; j < count + 1; ++j) {
stack.push(height[i]);
}
i++;
}
}
int count = 0;
while(!stack.isEmpty()) {
count++;
max = Math.max(max, stack.pop() * count);
}
return max;
}
thank you in advance
To find the space complexity take a look at the variables you declare and are larger than a single primitive variable. In fact I believe your space complexity will be determined my the array auxilary and the Stack stack. The size of the first one is pretty clear and I don't completely understand the second one but I see it's size will never be greater than the one of the array. So I would say the space complexity is O(size of(auxilary)) or O(N * M) where N=as.length() and M = as[0].length.
Now the time complexity is a bit trickier. You have two cycles over the whole auxilary array so for sure time complexity is at least O( N * M). You also have another cycle that invokes largestRectangleArea for each row of auxilary. If I get the code in this function correctly it seems this function is again linear, but I am not sure here. Since you know the logic better probably you will be able to compute its complexity better.
Hope this helps.

Categories