Java speedup processes / threads












1















I have a rather big ArrayList.



I have to go through every index, and do a expensive calculation



My first idea to speed it up was by putting it into a thread.
It works, but it is still extremely slow. I tinkered around the calculation, to make it less expensive, but its still to slow. The best solution i came up with is basically this one.



public void calculate(){
calculatePart(0);
calculatePart(1);
}

public void calculatePart(int offset) {
new Thread() {
@Override
public void run() {
int i = offset;
while(arrayList.size() > i) {
//Do the calulation
i +=2;
}
}
}.start();
}


Yet this feels like a lazy, unprofessional solution. That is why I'm asking if there is a cleaner and even faster solution










share|improve this question

























  • what sort of calculation are you exactly doing? Are you mutating the objects in the list or are you counting something and storing it in a variable?

    – Ryotsu
    Nov 23 '18 at 14:39













  • this is not about speed up of your algo but about parallelism; speed up begins with optimizing the algorithm hidden in the "do the calculation", IMHO

    – OznOg
    Nov 23 '18 at 14:41











  • Is the "big" calculation on every index of ArrrayList independent of each other? If it is independent, then you can go ahead with parallelizing, and the degree of parallelism can, of course, be greater then two.

    – Lavish Kothari
    Nov 23 '18 at 14:50













  • So you made two threads to process in parallel odd and even elements - why do you expect to see it will be much faster? probably it is a little. BTW it depends on how your "do calculation" looks like - if there is no point to pass control to another thread then second thread will take control only after "do calculation" done for one element by first thread...

    – Vadim
    Nov 23 '18 at 14:51






  • 1





    while(arrayList.size() > i) { means you change the size of the arrayList often. This is a very expensive operation.

    – Alexei Kaigorodov
    Nov 23 '18 at 14:58
















1















I have a rather big ArrayList.



I have to go through every index, and do a expensive calculation



My first idea to speed it up was by putting it into a thread.
It works, but it is still extremely slow. I tinkered around the calculation, to make it less expensive, but its still to slow. The best solution i came up with is basically this one.



public void calculate(){
calculatePart(0);
calculatePart(1);
}

public void calculatePart(int offset) {
new Thread() {
@Override
public void run() {
int i = offset;
while(arrayList.size() > i) {
//Do the calulation
i +=2;
}
}
}.start();
}


Yet this feels like a lazy, unprofessional solution. That is why I'm asking if there is a cleaner and even faster solution










share|improve this question

























  • what sort of calculation are you exactly doing? Are you mutating the objects in the list or are you counting something and storing it in a variable?

    – Ryotsu
    Nov 23 '18 at 14:39













  • this is not about speed up of your algo but about parallelism; speed up begins with optimizing the algorithm hidden in the "do the calculation", IMHO

    – OznOg
    Nov 23 '18 at 14:41











  • Is the "big" calculation on every index of ArrrayList independent of each other? If it is independent, then you can go ahead with parallelizing, and the degree of parallelism can, of course, be greater then two.

    – Lavish Kothari
    Nov 23 '18 at 14:50













  • So you made two threads to process in parallel odd and even elements - why do you expect to see it will be much faster? probably it is a little. BTW it depends on how your "do calculation" looks like - if there is no point to pass control to another thread then second thread will take control only after "do calculation" done for one element by first thread...

    – Vadim
    Nov 23 '18 at 14:51






  • 1





    while(arrayList.size() > i) { means you change the size of the arrayList often. This is a very expensive operation.

    – Alexei Kaigorodov
    Nov 23 '18 at 14:58














1












1








1








I have a rather big ArrayList.



I have to go through every index, and do a expensive calculation



My first idea to speed it up was by putting it into a thread.
It works, but it is still extremely slow. I tinkered around the calculation, to make it less expensive, but its still to slow. The best solution i came up with is basically this one.



public void calculate(){
calculatePart(0);
calculatePart(1);
}

public void calculatePart(int offset) {
new Thread() {
@Override
public void run() {
int i = offset;
while(arrayList.size() > i) {
//Do the calulation
i +=2;
}
}
}.start();
}


Yet this feels like a lazy, unprofessional solution. That is why I'm asking if there is a cleaner and even faster solution










share|improve this question
















I have a rather big ArrayList.



I have to go through every index, and do a expensive calculation



My first idea to speed it up was by putting it into a thread.
It works, but it is still extremely slow. I tinkered around the calculation, to make it less expensive, but its still to slow. The best solution i came up with is basically this one.



public void calculate(){
calculatePart(0);
calculatePart(1);
}

public void calculatePart(int offset) {
new Thread() {
@Override
public void run() {
int i = offset;
while(arrayList.size() > i) {
//Do the calulation
i +=2;
}
}
}.start();
}


Yet this feels like a lazy, unprofessional solution. That is why I'm asking if there is a cleaner and even faster solution







java multithreading






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 23 '18 at 17:04









Panagiotis Kanavos

55.3k483110




55.3k483110










asked Nov 23 '18 at 14:33









TigerdanTigerdan

62




62













  • what sort of calculation are you exactly doing? Are you mutating the objects in the list or are you counting something and storing it in a variable?

    – Ryotsu
    Nov 23 '18 at 14:39













  • this is not about speed up of your algo but about parallelism; speed up begins with optimizing the algorithm hidden in the "do the calculation", IMHO

    – OznOg
    Nov 23 '18 at 14:41











  • Is the "big" calculation on every index of ArrrayList independent of each other? If it is independent, then you can go ahead with parallelizing, and the degree of parallelism can, of course, be greater then two.

    – Lavish Kothari
    Nov 23 '18 at 14:50













  • So you made two threads to process in parallel odd and even elements - why do you expect to see it will be much faster? probably it is a little. BTW it depends on how your "do calculation" looks like - if there is no point to pass control to another thread then second thread will take control only after "do calculation" done for one element by first thread...

    – Vadim
    Nov 23 '18 at 14:51






  • 1





    while(arrayList.size() > i) { means you change the size of the arrayList often. This is a very expensive operation.

    – Alexei Kaigorodov
    Nov 23 '18 at 14:58



















  • what sort of calculation are you exactly doing? Are you mutating the objects in the list or are you counting something and storing it in a variable?

    – Ryotsu
    Nov 23 '18 at 14:39













  • this is not about speed up of your algo but about parallelism; speed up begins with optimizing the algorithm hidden in the "do the calculation", IMHO

    – OznOg
    Nov 23 '18 at 14:41











  • Is the "big" calculation on every index of ArrrayList independent of each other? If it is independent, then you can go ahead with parallelizing, and the degree of parallelism can, of course, be greater then two.

    – Lavish Kothari
    Nov 23 '18 at 14:50













  • So you made two threads to process in parallel odd and even elements - why do you expect to see it will be much faster? probably it is a little. BTW it depends on how your "do calculation" looks like - if there is no point to pass control to another thread then second thread will take control only after "do calculation" done for one element by first thread...

    – Vadim
    Nov 23 '18 at 14:51






  • 1





    while(arrayList.size() > i) { means you change the size of the arrayList often. This is a very expensive operation.

    – Alexei Kaigorodov
    Nov 23 '18 at 14:58

















what sort of calculation are you exactly doing? Are you mutating the objects in the list or are you counting something and storing it in a variable?

– Ryotsu
Nov 23 '18 at 14:39







what sort of calculation are you exactly doing? Are you mutating the objects in the list or are you counting something and storing it in a variable?

– Ryotsu
Nov 23 '18 at 14:39















this is not about speed up of your algo but about parallelism; speed up begins with optimizing the algorithm hidden in the "do the calculation", IMHO

– OznOg
Nov 23 '18 at 14:41





this is not about speed up of your algo but about parallelism; speed up begins with optimizing the algorithm hidden in the "do the calculation", IMHO

– OznOg
Nov 23 '18 at 14:41













Is the "big" calculation on every index of ArrrayList independent of each other? If it is independent, then you can go ahead with parallelizing, and the degree of parallelism can, of course, be greater then two.

– Lavish Kothari
Nov 23 '18 at 14:50







Is the "big" calculation on every index of ArrrayList independent of each other? If it is independent, then you can go ahead with parallelizing, and the degree of parallelism can, of course, be greater then two.

– Lavish Kothari
Nov 23 '18 at 14:50















So you made two threads to process in parallel odd and even elements - why do you expect to see it will be much faster? probably it is a little. BTW it depends on how your "do calculation" looks like - if there is no point to pass control to another thread then second thread will take control only after "do calculation" done for one element by first thread...

– Vadim
Nov 23 '18 at 14:51





So you made two threads to process in parallel odd and even elements - why do you expect to see it will be much faster? probably it is a little. BTW it depends on how your "do calculation" looks like - if there is no point to pass control to another thread then second thread will take control only after "do calculation" done for one element by first thread...

– Vadim
Nov 23 '18 at 14:51




1




1





while(arrayList.size() > i) { means you change the size of the arrayList often. This is a very expensive operation.

– Alexei Kaigorodov
Nov 23 '18 at 14:58





while(arrayList.size() > i) { means you change the size of the arrayList often. This is a very expensive operation.

– Alexei Kaigorodov
Nov 23 '18 at 14:58












2 Answers
2






active

oldest

votes


















2














High theoretically speaking:
if you have X elements and your calculation must perform N operations on each one then
your computer(processor) must perform X*N operations total, then...



Parallel threads can make it faster only if in the calculation operations there are some of them when thread is waiting (e.g. File or Network operations). That time can be used by other threads. But if all operations are pure CPU (e.g. mathematics) and thread is not waiting - required time to perform X*N operations stays the same.



Also each tread must give other threads ability to take control over CPU at some point. It happens automatically between methods calls or if you have Thread.yield() call in your code.



as example method like:



public void run()
{
long a=0;
for (long i=1; i < Long.MAX_VALUE; i++)
{
a+=i;
}
}


will not give other thread a chance to take control over CPU until it fully completed and exited.






share|improve this answer
























  • True for a single processor, but present day CPUs have multiple processors and thus can handle multiple tasks at the same time, which reduces the total execution time.

    – uneq95
    Nov 24 '18 at 23:52











  • From Java prospective it does not matter. Multi-processors/cores handle by OS not by JVM. JVM is nothing else but another process in OS

    – Vadim
    Nov 26 '18 at 14:59













  • What do you mean, java can't create threads and get them to do tasks in parallel? What I meant to say was that doing tasks in parallel will reduce the effective time to process all elements, however the work will always remain the same. You have assumed, in your answer, that we only have one processor. What am I missing here?

    – uneq95
    Nov 27 '18 at 12:19



















0














Assuming that doing task on each element doesn't lead to data races, you could leverage the power of parallelism. To maximize the number of computations occurring at the same time, you would have to give tasks to each of the processors available in your system.



In Java, you can get the number of processors (cores) available using this:



int parallelism = Runtime.getRuntime().availableProcessors();


The idea is to create number of threads equal to the available processors.



So, if you have 4 processors available, you can create 4 threads and ask them to process items at a gap of 4.Suppose you have a list of size 10, which needs to be processed in parallel.



Then,



Thread 1 processes items at index 0,4,8

Thread 2 processes items at index 1,5,9

Thread 3 processes items at index 2,6

Thread 4 processes items at index 3,7



I tried to simulate your scenario with the following code:



import java.util.Arrays;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

public class SpeedUpTest {

public static void main(String args) throws InterruptedException, ExecutionException {
long seqTime, twoThreadTime, multiThreadTime;
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);

long time = System.currentTimeMillis();
sequentialProcessing(list);
seqTime = System.currentTimeMillis() - time;

int parallelism = 2;
ExecutorService executorService = Executors.newFixedThreadPool(parallelism);
time = System.currentTimeMillis();
List<Future> tasks = new ArrayList<>();
for (int offset = 0; offset < parallelism; offset++) {

int finalParallelism = parallelism;
int finalOffset = offset;
Future task = executorService.submit(() -> {
int i = finalOffset;
while (list.size() > i) {
try {
processItem(list.get(i));
} catch (InterruptedException e) {
e.printStackTrace();
}
i += finalParallelism;
}
});
tasks.add(task);
}
for (Future task : tasks) {
task.get();
}
twoThreadTime = System.currentTimeMillis() - time;

parallelism = Runtime.getRuntime().availableProcessors();
executorService = Executors.newFixedThreadPool(parallelism);
tasks = new ArrayList<>();
time = System.currentTimeMillis();
for (int offset = 0; offset < parallelism; offset++) {

int finalParallelism = parallelism;
int finalOffset = offset;
Future task = executorService.submit(() -> {
int i = finalOffset;
while (list.size() > i) {
try {
processItem(list.get(i));
} catch (InterruptedException e) {
e.printStackTrace();
}
i += finalParallelism;
}
});
tasks.add(task);
}
for (Future task : tasks) {
task.get();
}
multiThreadTime = System.currentTimeMillis() - time;
log("RESULTS:");
log("Total time for sequential execution : " + seqTime / 1000.0 + " seconds");
log("Total time for execution with 2 threads: " + twoThreadTime / 1000.0 + " seconds");
log("Total time for execution with " + parallelism + " threads: " + multiThreadTime / 1000.0 + " seconds");


}

private static void log(String msg) {
System.out.println(msg);
}

private static void processItem(int index) throws InterruptedException {
Thread.sleep(5000);
}

private static void sequentialProcessing(List<Integer> list) throws InterruptedException {

for (int i = 0; i < list.size(); i++) {
processItem(list.get(i));
}
}

}


OUTPUT:




RESULTS:



Total time for sequential execution : 50.001 seconds



Total time for execution with 2 threads: 25.102 seconds



Total time for execution with 4 threads: 15.002 seconds







share|improve this answer























    Your Answer






    StackExchange.ifUsing("editor", function () {
    StackExchange.using("externalEditor", function () {
    StackExchange.using("snippets", function () {
    StackExchange.snippets.init();
    });
    });
    }, "code-snippets");

    StackExchange.ready(function() {
    var channelOptions = {
    tags: "".split(" "),
    id: "1"
    };
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function() {
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled) {
    StackExchange.using("snippets", function() {
    createEditor();
    });
    }
    else {
    createEditor();
    }
    });

    function createEditor() {
    StackExchange.prepareEditor({
    heartbeatType: 'answer',
    autoActivateHeartbeat: false,
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader: {
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    },
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    });


    }
    });














    draft saved

    draft discarded


















    StackExchange.ready(
    function () {
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53448577%2fjava-speedup-processes-threads%23new-answer', 'question_page');
    }
    );

    Post as a guest















    Required, but never shown

























    2 Answers
    2






    active

    oldest

    votes








    2 Answers
    2






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    2














    High theoretically speaking:
    if you have X elements and your calculation must perform N operations on each one then
    your computer(processor) must perform X*N operations total, then...



    Parallel threads can make it faster only if in the calculation operations there are some of them when thread is waiting (e.g. File or Network operations). That time can be used by other threads. But if all operations are pure CPU (e.g. mathematics) and thread is not waiting - required time to perform X*N operations stays the same.



    Also each tread must give other threads ability to take control over CPU at some point. It happens automatically between methods calls or if you have Thread.yield() call in your code.



    as example method like:



    public void run()
    {
    long a=0;
    for (long i=1; i < Long.MAX_VALUE; i++)
    {
    a+=i;
    }
    }


    will not give other thread a chance to take control over CPU until it fully completed and exited.






    share|improve this answer
























    • True for a single processor, but present day CPUs have multiple processors and thus can handle multiple tasks at the same time, which reduces the total execution time.

      – uneq95
      Nov 24 '18 at 23:52











    • From Java prospective it does not matter. Multi-processors/cores handle by OS not by JVM. JVM is nothing else but another process in OS

      – Vadim
      Nov 26 '18 at 14:59













    • What do you mean, java can't create threads and get them to do tasks in parallel? What I meant to say was that doing tasks in parallel will reduce the effective time to process all elements, however the work will always remain the same. You have assumed, in your answer, that we only have one processor. What am I missing here?

      – uneq95
      Nov 27 '18 at 12:19
















    2














    High theoretically speaking:
    if you have X elements and your calculation must perform N operations on each one then
    your computer(processor) must perform X*N operations total, then...



    Parallel threads can make it faster only if in the calculation operations there are some of them when thread is waiting (e.g. File or Network operations). That time can be used by other threads. But if all operations are pure CPU (e.g. mathematics) and thread is not waiting - required time to perform X*N operations stays the same.



    Also each tread must give other threads ability to take control over CPU at some point. It happens automatically between methods calls or if you have Thread.yield() call in your code.



    as example method like:



    public void run()
    {
    long a=0;
    for (long i=1; i < Long.MAX_VALUE; i++)
    {
    a+=i;
    }
    }


    will not give other thread a chance to take control over CPU until it fully completed and exited.






    share|improve this answer
























    • True for a single processor, but present day CPUs have multiple processors and thus can handle multiple tasks at the same time, which reduces the total execution time.

      – uneq95
      Nov 24 '18 at 23:52











    • From Java prospective it does not matter. Multi-processors/cores handle by OS not by JVM. JVM is nothing else but another process in OS

      – Vadim
      Nov 26 '18 at 14:59













    • What do you mean, java can't create threads and get them to do tasks in parallel? What I meant to say was that doing tasks in parallel will reduce the effective time to process all elements, however the work will always remain the same. You have assumed, in your answer, that we only have one processor. What am I missing here?

      – uneq95
      Nov 27 '18 at 12:19














    2












    2








    2







    High theoretically speaking:
    if you have X elements and your calculation must perform N operations on each one then
    your computer(processor) must perform X*N operations total, then...



    Parallel threads can make it faster only if in the calculation operations there are some of them when thread is waiting (e.g. File or Network operations). That time can be used by other threads. But if all operations are pure CPU (e.g. mathematics) and thread is not waiting - required time to perform X*N operations stays the same.



    Also each tread must give other threads ability to take control over CPU at some point. It happens automatically between methods calls or if you have Thread.yield() call in your code.



    as example method like:



    public void run()
    {
    long a=0;
    for (long i=1; i < Long.MAX_VALUE; i++)
    {
    a+=i;
    }
    }


    will not give other thread a chance to take control over CPU until it fully completed and exited.






    share|improve this answer













    High theoretically speaking:
    if you have X elements and your calculation must perform N operations on each one then
    your computer(processor) must perform X*N operations total, then...



    Parallel threads can make it faster only if in the calculation operations there are some of them when thread is waiting (e.g. File or Network operations). That time can be used by other threads. But if all operations are pure CPU (e.g. mathematics) and thread is not waiting - required time to perform X*N operations stays the same.



    Also each tread must give other threads ability to take control over CPU at some point. It happens automatically between methods calls or if you have Thread.yield() call in your code.



    as example method like:



    public void run()
    {
    long a=0;
    for (long i=1; i < Long.MAX_VALUE; i++)
    {
    a+=i;
    }
    }


    will not give other thread a chance to take control over CPU until it fully completed and exited.







    share|improve this answer












    share|improve this answer



    share|improve this answer










    answered Nov 23 '18 at 15:18









    VadimVadim

    3,4462622




    3,4462622













    • True for a single processor, but present day CPUs have multiple processors and thus can handle multiple tasks at the same time, which reduces the total execution time.

      – uneq95
      Nov 24 '18 at 23:52











    • From Java prospective it does not matter. Multi-processors/cores handle by OS not by JVM. JVM is nothing else but another process in OS

      – Vadim
      Nov 26 '18 at 14:59













    • What do you mean, java can't create threads and get them to do tasks in parallel? What I meant to say was that doing tasks in parallel will reduce the effective time to process all elements, however the work will always remain the same. You have assumed, in your answer, that we only have one processor. What am I missing here?

      – uneq95
      Nov 27 '18 at 12:19



















    • True for a single processor, but present day CPUs have multiple processors and thus can handle multiple tasks at the same time, which reduces the total execution time.

      – uneq95
      Nov 24 '18 at 23:52











    • From Java prospective it does not matter. Multi-processors/cores handle by OS not by JVM. JVM is nothing else but another process in OS

      – Vadim
      Nov 26 '18 at 14:59













    • What do you mean, java can't create threads and get them to do tasks in parallel? What I meant to say was that doing tasks in parallel will reduce the effective time to process all elements, however the work will always remain the same. You have assumed, in your answer, that we only have one processor. What am I missing here?

      – uneq95
      Nov 27 '18 at 12:19

















    True for a single processor, but present day CPUs have multiple processors and thus can handle multiple tasks at the same time, which reduces the total execution time.

    – uneq95
    Nov 24 '18 at 23:52





    True for a single processor, but present day CPUs have multiple processors and thus can handle multiple tasks at the same time, which reduces the total execution time.

    – uneq95
    Nov 24 '18 at 23:52













    From Java prospective it does not matter. Multi-processors/cores handle by OS not by JVM. JVM is nothing else but another process in OS

    – Vadim
    Nov 26 '18 at 14:59







    From Java prospective it does not matter. Multi-processors/cores handle by OS not by JVM. JVM is nothing else but another process in OS

    – Vadim
    Nov 26 '18 at 14:59















    What do you mean, java can't create threads and get them to do tasks in parallel? What I meant to say was that doing tasks in parallel will reduce the effective time to process all elements, however the work will always remain the same. You have assumed, in your answer, that we only have one processor. What am I missing here?

    – uneq95
    Nov 27 '18 at 12:19





    What do you mean, java can't create threads and get them to do tasks in parallel? What I meant to say was that doing tasks in parallel will reduce the effective time to process all elements, however the work will always remain the same. You have assumed, in your answer, that we only have one processor. What am I missing here?

    – uneq95
    Nov 27 '18 at 12:19













    0














    Assuming that doing task on each element doesn't lead to data races, you could leverage the power of parallelism. To maximize the number of computations occurring at the same time, you would have to give tasks to each of the processors available in your system.



    In Java, you can get the number of processors (cores) available using this:



    int parallelism = Runtime.getRuntime().availableProcessors();


    The idea is to create number of threads equal to the available processors.



    So, if you have 4 processors available, you can create 4 threads and ask them to process items at a gap of 4.Suppose you have a list of size 10, which needs to be processed in parallel.



    Then,



    Thread 1 processes items at index 0,4,8

    Thread 2 processes items at index 1,5,9

    Thread 3 processes items at index 2,6

    Thread 4 processes items at index 3,7



    I tried to simulate your scenario with the following code:



    import java.util.Arrays;
    import java.util.ArrayList;
    import java.util.List;
    import java.util.concurrent.ExecutionException;
    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    import java.util.concurrent.Future;

    public class SpeedUpTest {

    public static void main(String args) throws InterruptedException, ExecutionException {
    long seqTime, twoThreadTime, multiThreadTime;
    List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);

    long time = System.currentTimeMillis();
    sequentialProcessing(list);
    seqTime = System.currentTimeMillis() - time;

    int parallelism = 2;
    ExecutorService executorService = Executors.newFixedThreadPool(parallelism);
    time = System.currentTimeMillis();
    List<Future> tasks = new ArrayList<>();
    for (int offset = 0; offset < parallelism; offset++) {

    int finalParallelism = parallelism;
    int finalOffset = offset;
    Future task = executorService.submit(() -> {
    int i = finalOffset;
    while (list.size() > i) {
    try {
    processItem(list.get(i));
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    i += finalParallelism;
    }
    });
    tasks.add(task);
    }
    for (Future task : tasks) {
    task.get();
    }
    twoThreadTime = System.currentTimeMillis() - time;

    parallelism = Runtime.getRuntime().availableProcessors();
    executorService = Executors.newFixedThreadPool(parallelism);
    tasks = new ArrayList<>();
    time = System.currentTimeMillis();
    for (int offset = 0; offset < parallelism; offset++) {

    int finalParallelism = parallelism;
    int finalOffset = offset;
    Future task = executorService.submit(() -> {
    int i = finalOffset;
    while (list.size() > i) {
    try {
    processItem(list.get(i));
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    i += finalParallelism;
    }
    });
    tasks.add(task);
    }
    for (Future task : tasks) {
    task.get();
    }
    multiThreadTime = System.currentTimeMillis() - time;
    log("RESULTS:");
    log("Total time for sequential execution : " + seqTime / 1000.0 + " seconds");
    log("Total time for execution with 2 threads: " + twoThreadTime / 1000.0 + " seconds");
    log("Total time for execution with " + parallelism + " threads: " + multiThreadTime / 1000.0 + " seconds");


    }

    private static void log(String msg) {
    System.out.println(msg);
    }

    private static void processItem(int index) throws InterruptedException {
    Thread.sleep(5000);
    }

    private static void sequentialProcessing(List<Integer> list) throws InterruptedException {

    for (int i = 0; i < list.size(); i++) {
    processItem(list.get(i));
    }
    }

    }


    OUTPUT:




    RESULTS:



    Total time for sequential execution : 50.001 seconds



    Total time for execution with 2 threads: 25.102 seconds



    Total time for execution with 4 threads: 15.002 seconds







    share|improve this answer




























      0














      Assuming that doing task on each element doesn't lead to data races, you could leverage the power of parallelism. To maximize the number of computations occurring at the same time, you would have to give tasks to each of the processors available in your system.



      In Java, you can get the number of processors (cores) available using this:



      int parallelism = Runtime.getRuntime().availableProcessors();


      The idea is to create number of threads equal to the available processors.



      So, if you have 4 processors available, you can create 4 threads and ask them to process items at a gap of 4.Suppose you have a list of size 10, which needs to be processed in parallel.



      Then,



      Thread 1 processes items at index 0,4,8

      Thread 2 processes items at index 1,5,9

      Thread 3 processes items at index 2,6

      Thread 4 processes items at index 3,7



      I tried to simulate your scenario with the following code:



      import java.util.Arrays;
      import java.util.ArrayList;
      import java.util.List;
      import java.util.concurrent.ExecutionException;
      import java.util.concurrent.ExecutorService;
      import java.util.concurrent.Executors;
      import java.util.concurrent.Future;

      public class SpeedUpTest {

      public static void main(String args) throws InterruptedException, ExecutionException {
      long seqTime, twoThreadTime, multiThreadTime;
      List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);

      long time = System.currentTimeMillis();
      sequentialProcessing(list);
      seqTime = System.currentTimeMillis() - time;

      int parallelism = 2;
      ExecutorService executorService = Executors.newFixedThreadPool(parallelism);
      time = System.currentTimeMillis();
      List<Future> tasks = new ArrayList<>();
      for (int offset = 0; offset < parallelism; offset++) {

      int finalParallelism = parallelism;
      int finalOffset = offset;
      Future task = executorService.submit(() -> {
      int i = finalOffset;
      while (list.size() > i) {
      try {
      processItem(list.get(i));
      } catch (InterruptedException e) {
      e.printStackTrace();
      }
      i += finalParallelism;
      }
      });
      tasks.add(task);
      }
      for (Future task : tasks) {
      task.get();
      }
      twoThreadTime = System.currentTimeMillis() - time;

      parallelism = Runtime.getRuntime().availableProcessors();
      executorService = Executors.newFixedThreadPool(parallelism);
      tasks = new ArrayList<>();
      time = System.currentTimeMillis();
      for (int offset = 0; offset < parallelism; offset++) {

      int finalParallelism = parallelism;
      int finalOffset = offset;
      Future task = executorService.submit(() -> {
      int i = finalOffset;
      while (list.size() > i) {
      try {
      processItem(list.get(i));
      } catch (InterruptedException e) {
      e.printStackTrace();
      }
      i += finalParallelism;
      }
      });
      tasks.add(task);
      }
      for (Future task : tasks) {
      task.get();
      }
      multiThreadTime = System.currentTimeMillis() - time;
      log("RESULTS:");
      log("Total time for sequential execution : " + seqTime / 1000.0 + " seconds");
      log("Total time for execution with 2 threads: " + twoThreadTime / 1000.0 + " seconds");
      log("Total time for execution with " + parallelism + " threads: " + multiThreadTime / 1000.0 + " seconds");


      }

      private static void log(String msg) {
      System.out.println(msg);
      }

      private static void processItem(int index) throws InterruptedException {
      Thread.sleep(5000);
      }

      private static void sequentialProcessing(List<Integer> list) throws InterruptedException {

      for (int i = 0; i < list.size(); i++) {
      processItem(list.get(i));
      }
      }

      }


      OUTPUT:




      RESULTS:



      Total time for sequential execution : 50.001 seconds



      Total time for execution with 2 threads: 25.102 seconds



      Total time for execution with 4 threads: 15.002 seconds







      share|improve this answer


























        0












        0








        0







        Assuming that doing task on each element doesn't lead to data races, you could leverage the power of parallelism. To maximize the number of computations occurring at the same time, you would have to give tasks to each of the processors available in your system.



        In Java, you can get the number of processors (cores) available using this:



        int parallelism = Runtime.getRuntime().availableProcessors();


        The idea is to create number of threads equal to the available processors.



        So, if you have 4 processors available, you can create 4 threads and ask them to process items at a gap of 4.Suppose you have a list of size 10, which needs to be processed in parallel.



        Then,



        Thread 1 processes items at index 0,4,8

        Thread 2 processes items at index 1,5,9

        Thread 3 processes items at index 2,6

        Thread 4 processes items at index 3,7



        I tried to simulate your scenario with the following code:



        import java.util.Arrays;
        import java.util.ArrayList;
        import java.util.List;
        import java.util.concurrent.ExecutionException;
        import java.util.concurrent.ExecutorService;
        import java.util.concurrent.Executors;
        import java.util.concurrent.Future;

        public class SpeedUpTest {

        public static void main(String args) throws InterruptedException, ExecutionException {
        long seqTime, twoThreadTime, multiThreadTime;
        List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);

        long time = System.currentTimeMillis();
        sequentialProcessing(list);
        seqTime = System.currentTimeMillis() - time;

        int parallelism = 2;
        ExecutorService executorService = Executors.newFixedThreadPool(parallelism);
        time = System.currentTimeMillis();
        List<Future> tasks = new ArrayList<>();
        for (int offset = 0; offset < parallelism; offset++) {

        int finalParallelism = parallelism;
        int finalOffset = offset;
        Future task = executorService.submit(() -> {
        int i = finalOffset;
        while (list.size() > i) {
        try {
        processItem(list.get(i));
        } catch (InterruptedException e) {
        e.printStackTrace();
        }
        i += finalParallelism;
        }
        });
        tasks.add(task);
        }
        for (Future task : tasks) {
        task.get();
        }
        twoThreadTime = System.currentTimeMillis() - time;

        parallelism = Runtime.getRuntime().availableProcessors();
        executorService = Executors.newFixedThreadPool(parallelism);
        tasks = new ArrayList<>();
        time = System.currentTimeMillis();
        for (int offset = 0; offset < parallelism; offset++) {

        int finalParallelism = parallelism;
        int finalOffset = offset;
        Future task = executorService.submit(() -> {
        int i = finalOffset;
        while (list.size() > i) {
        try {
        processItem(list.get(i));
        } catch (InterruptedException e) {
        e.printStackTrace();
        }
        i += finalParallelism;
        }
        });
        tasks.add(task);
        }
        for (Future task : tasks) {
        task.get();
        }
        multiThreadTime = System.currentTimeMillis() - time;
        log("RESULTS:");
        log("Total time for sequential execution : " + seqTime / 1000.0 + " seconds");
        log("Total time for execution with 2 threads: " + twoThreadTime / 1000.0 + " seconds");
        log("Total time for execution with " + parallelism + " threads: " + multiThreadTime / 1000.0 + " seconds");


        }

        private static void log(String msg) {
        System.out.println(msg);
        }

        private static void processItem(int index) throws InterruptedException {
        Thread.sleep(5000);
        }

        private static void sequentialProcessing(List<Integer> list) throws InterruptedException {

        for (int i = 0; i < list.size(); i++) {
        processItem(list.get(i));
        }
        }

        }


        OUTPUT:




        RESULTS:



        Total time for sequential execution : 50.001 seconds



        Total time for execution with 2 threads: 25.102 seconds



        Total time for execution with 4 threads: 15.002 seconds







        share|improve this answer













        Assuming that doing task on each element doesn't lead to data races, you could leverage the power of parallelism. To maximize the number of computations occurring at the same time, you would have to give tasks to each of the processors available in your system.



        In Java, you can get the number of processors (cores) available using this:



        int parallelism = Runtime.getRuntime().availableProcessors();


        The idea is to create number of threads equal to the available processors.



        So, if you have 4 processors available, you can create 4 threads and ask them to process items at a gap of 4.Suppose you have a list of size 10, which needs to be processed in parallel.



        Then,



        Thread 1 processes items at index 0,4,8

        Thread 2 processes items at index 1,5,9

        Thread 3 processes items at index 2,6

        Thread 4 processes items at index 3,7



        I tried to simulate your scenario with the following code:



        import java.util.Arrays;
        import java.util.ArrayList;
        import java.util.List;
        import java.util.concurrent.ExecutionException;
        import java.util.concurrent.ExecutorService;
        import java.util.concurrent.Executors;
        import java.util.concurrent.Future;

        public class SpeedUpTest {

        public static void main(String args) throws InterruptedException, ExecutionException {
        long seqTime, twoThreadTime, multiThreadTime;
        List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);

        long time = System.currentTimeMillis();
        sequentialProcessing(list);
        seqTime = System.currentTimeMillis() - time;

        int parallelism = 2;
        ExecutorService executorService = Executors.newFixedThreadPool(parallelism);
        time = System.currentTimeMillis();
        List<Future> tasks = new ArrayList<>();
        for (int offset = 0; offset < parallelism; offset++) {

        int finalParallelism = parallelism;
        int finalOffset = offset;
        Future task = executorService.submit(() -> {
        int i = finalOffset;
        while (list.size() > i) {
        try {
        processItem(list.get(i));
        } catch (InterruptedException e) {
        e.printStackTrace();
        }
        i += finalParallelism;
        }
        });
        tasks.add(task);
        }
        for (Future task : tasks) {
        task.get();
        }
        twoThreadTime = System.currentTimeMillis() - time;

        parallelism = Runtime.getRuntime().availableProcessors();
        executorService = Executors.newFixedThreadPool(parallelism);
        tasks = new ArrayList<>();
        time = System.currentTimeMillis();
        for (int offset = 0; offset < parallelism; offset++) {

        int finalParallelism = parallelism;
        int finalOffset = offset;
        Future task = executorService.submit(() -> {
        int i = finalOffset;
        while (list.size() > i) {
        try {
        processItem(list.get(i));
        } catch (InterruptedException e) {
        e.printStackTrace();
        }
        i += finalParallelism;
        }
        });
        tasks.add(task);
        }
        for (Future task : tasks) {
        task.get();
        }
        multiThreadTime = System.currentTimeMillis() - time;
        log("RESULTS:");
        log("Total time for sequential execution : " + seqTime / 1000.0 + " seconds");
        log("Total time for execution with 2 threads: " + twoThreadTime / 1000.0 + " seconds");
        log("Total time for execution with " + parallelism + " threads: " + multiThreadTime / 1000.0 + " seconds");


        }

        private static void log(String msg) {
        System.out.println(msg);
        }

        private static void processItem(int index) throws InterruptedException {
        Thread.sleep(5000);
        }

        private static void sequentialProcessing(List<Integer> list) throws InterruptedException {

        for (int i = 0; i < list.size(); i++) {
        processItem(list.get(i));
        }
        }

        }


        OUTPUT:




        RESULTS:



        Total time for sequential execution : 50.001 seconds



        Total time for execution with 2 threads: 25.102 seconds



        Total time for execution with 4 threads: 15.002 seconds








        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered Nov 24 '18 at 23:23









        uneq95uneq95

        863616




        863616






























            draft saved

            draft discarded




















































            Thanks for contributing an answer to Stack Overflow!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53448577%2fjava-speedup-processes-threads%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            Popular posts from this blog

            Costa Masnaga

            Fotorealismo

            Sidney Franklin