Java加速进程/线程

时间:2018-11-23 14:33:23

标签: java multithreading

我有一个相当大的ArrayList。

我必须仔细检查每个索引,并进行昂贵的计算

我加速它的第一个想法是将其放入线程中。 它可以工作,但是仍然非常慢。我对计算进行了修改,以使其更便宜,但仍然很慢。我想出的最好的解决方案基本上就是这个。

if(isset($_POST['btnLogin']))
{
$username = $_POST['txtusername'];
$pass_word = $_POST['txtpassword'];
$hashed_password = crypt(sha1($pass_word));


$sqlQuery  = "SELECT * from users WHERE username = :username AND password = :password" ;
$statement = $conn->prepare($sqlQuery);
$statement->execute(array(':username' =>$user , ':password'=>$hashed_password));

while($row = $statement->fetch_object())
{
    $id       = $row->id;
    $username = $row->username;
    $password = $row->password;

    if(strcmp('$password', '$hashed_password') == 0)
    {
        echo '<script type="text/javascript">console.log("Success");</script>';
    }
    else
    {
        echo '<script type="text/javascript">console.log("Failed");</script>';
    }

}

但是,这感觉像是一个懒惰,不专业的解决方案。这就是为什么我要问是否有更清洁,甚至更快的解决方案

2 个答案:

答案 0 :(得分:2)

从理论上讲很高: 如果您有X个元素,并且您的计算必须对每个元素执行N次运算,则 您的计算机(处理器)必须总共执行X * N次操作,然后...

只有在计算操作中有一些线程正在等待时,并行线程才能使其速度更快(例如,文件或网络操作)。该时间可以由其他线程使用。但是,如果所有操作都是纯CPU(例如数学)并且线程没有等待-执行X * N操作所需的时间保持不变。

每个踏步还必须在某些时候赋予其他线程控制CPU的能力。它会在方法调用之间自动执行,或者在代码中调用Thread.yield()时自动发生。

作为示例方法,例如:

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

在完全完成并退出之前,不会给其他线程控制CPU的机会。

答案 1 :(得分:0)

假设在每个元素上执行任务不会导致数据争用,则可以利用并行功能。为了最大化同时进行的计算数量,您必须将任务分配给系统中可用的每个处理器。

在Java中,您可以使用以下方法获得可用的处理器(核心)数量:

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

想法是创建等于可用处理器的线程数。

因此,如果有4个处理器可用,则可以创建4个线程,并要求它们以4的间隔进行处理。假设您有一个大小为10的列表,需要并行处理。

然后

线程1处理索引为0、4、8的项目
线程2处理索引为1,5,9的项目
线程3处理索引为2,6的项目
线程4处理索引为3,7的项目

我尝试使用以下代码模拟您的情况:

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));
        }
    }

}

输出:

  

结果:

     

顺序执行的总时间:50.001秒

     

使用2个线程执行的总时间:25.102秒

     

使用4个线程执行的总时间:15.002秒