Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/url/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 为什么添加System.out.println会使线程运行得更快?_Java_Multithreading - Fatal编程技术网

Java 为什么添加System.out.println会使线程运行得更快?

Java 为什么添加System.out.println会使线程运行得更快?,java,multithreading,Java,Multithreading,我在尝试各种方法,使大型计算并行运行。除了显式创建和启动Thread实例时(速度要慢得多),这一点与预期一样有效。我添加了一些println输出,以检查线程是否真的并行运行,但这一更改使它更快。速度从“超过一秒”到“几十毫秒”,结果是可重复的 特别奇怪:ArrayList没有慢的问题,println没有明显的区别,但是LinkedList很慢,直到我添加了一些println 我用Java8在Windows10上运行这个。我还尝试了Java11和Java12,但速度并没有变慢(所以无意义的输出不能

我在尝试各种方法,使大型计算并行运行。除了显式创建和启动
Thread
实例时(速度要慢得多),这一点与预期一样有效。我添加了一些println输出,以检查线程是否真的并行运行,但这一更改使它更快。速度从“超过一秒”到“几十毫秒”,结果是可重复的

特别奇怪:
ArrayList
没有慢的问题,
println
没有明显的区别,但是
LinkedList
很慢,直到我添加了一些
println

我用Java8在Windows10上运行这个。我还尝试了Java11和Java12,但速度并没有变慢(所以无意义的输出不能使速度更快)

我的问题不是如何使它更快-我实际上不需要运行这段代码,我可以用另一种方式使它并行(我推荐streams)。我的问题是如何通过打印一些输出来加快线程的速度,或者如果您更喜欢,那么首先为什么它会变慢

我试着改变线程的数量:一个线程(!)的奇怪现象消失了,但是有两个或更多的线程出现了(我在我的机器上测试了两倍的内核数量)

我尝试过改变正在处理的列表的大小,但只证明较小的列表可以处理得更快

我尝试改变输出:两个println输出似乎比一个输出更能提高速度,而在线程寿命结束时打印的效果比开始时小

我确保这不是GC效应(巨大的堆,并检查了GC日志)

这是我运行的代码

import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;

public class ListAddThreads {
    private static final int SIZE    = 20000000;
    private static final int REPEATS = 3;
    private static final int THREADS = Runtime.getRuntime().availableProcessors() / 2;

    private static String log = "none";

    public static void main( String[] args ) {
        if( args.length > 0 ) switch( args[0] ) {
            case "some":
            case "more":
            case "lots":
                log = args[0];
        }

        System.out.println( "Array List:" );
        List<Integer>listA = new ArrayList<>(SIZE);
        for( int i = 0; i < SIZE; i++ )
            listA.add( i );
        for( int i = 0; i < REPEATS; i++ )
            add( listA );

        System.out.println( "\nLinked List:" );
        List<Integer>listL = new LinkedList<>(listA);
        for( int i = 0; i < REPEATS; i++ )
            add( listL );
    }

    private static class AdderThread extends Thread {
        private long          result = 0;
        private List<Integer> list;
        private int           from;
        private int           to;

        AdderThread( List<Integer> list, int from, int to ) {
            this.list = list;
            this.from = from;
            this.to   = to;
        }

        long getResult() {
            return result;
        }

        public void run() {
            switch( log ) {
                case "some":
                    System.err.println( "string literal" );
                    break;
                case "more":
                    System.err.println( Thread.currentThread().getName() + " starting" );
                    break;
                case "lots":
                    System.err.println( "string literal" );
                    System.err.println( Thread.currentThread().getName() + " starting" );
                    break;
            }
            Iterator<Integer> it = list.iterator();
            for( int i = 0; i < to; i++ ) {
                Integer j = it.next();
                if( i >= from )
                    result += j;
            }
        }
    }

    private static void add( List<Integer> list ) {
        long          start  = System.currentTimeMillis();
        AdderThread[] adders = new AdderThread[THREADS];
        int           size   = list.size() / THREADS;

        for( int i = 0; i < THREADS; i++ ) {
            int from = i * size;
            int to   = i == THREADS - 1 ? list.size() : (i + 1) * size;

            adders[i] = new AdderThread( list, from, to );
        }
        for( int i = 0; i < THREADS; i++ ) {
            adders[i].start();
        }
        long result = 0;
        try {
            for( int i = 0; i < THREADS; i++ ) {
                adders[i].join();
                result += adders[i].getResult();
            }
        } catch ( InterruptedException x ) {
            throw new RuntimeException( "Adder thread interrupted.", x );
        }
        System.out.println( "Sum: " + result + ", time: " + (System.currentTimeMillis() - start) );
    }
}

看:你有没有用2-10秒的时间来测试它?线程管理和设置需要一些时间,因为它运行的时间越长,对时间测量的一些短期影响就越小。System.out.println(…)会减慢进程。如果你有一个进程,你可以检查它,如果你输出所有100毫秒,只有每秒1或只有最终结果。与运行计算相比,输出需要更多的时间。e、 在输入上迭代搜索匹配的散列值。对于本质上是
int-sum=listA.stream().mapToInt(Integer::intValue.sum())的内容,这是大量代码您应该做的更改是使用基准测试您的代码,并查看是否得到相同的结果。请参阅:您是否使用2-10秒的持续时间对其进行了测试?线程管理和设置需要一些时间,因为它运行的时间越长,对时间测量的一些短期影响就越小。System.out.println(…)会减慢进程。如果你有一个进程,你可以检查它,如果你输出所有100毫秒,只有每秒1或只有最终结果。与运行计算相比,输出需要更多的时间。e、 在输入上迭代搜索匹配的散列值。对于本质上是
int-sum=listA.stream().mapToInt(Integer::intValue.sum())的内容,这是大量代码您应该做的更改是用来对代码进行基准测试,看看是否得到相同的结果。
java -Xms4G -Xmx4G -XX:+PrintGCDetails -Xloggc:ListAddThreads_none_gc.log ListAddThreads none  2>nul
Array List:
Sum: 199999990000000, time: 62
Sum: 199999990000000, time: 157
Sum: 199999990000000, time: 62

Linked List:
Sum: 199999990000000, time: 3343
Sum: 199999990000000, time: 1814
Sum: 199999990000000, time: 1796

java -Xms4G -Xmx4G -XX:+PrintGCDetails -Xloggc:ListAddThreads_some_gc.log ListAddThreads some  2>nul
Array List:
Sum: 199999990000000, time: 50
Sum: 199999990000000, time: 58
Sum: 199999990000000, time: 56

Linked List:
Sum: 199999990000000, time: 2777
Sum: 199999990000000, time: 560
Sum: 199999990000000, time: 527

java -Xms4G -Xmx4G -XX:+PrintGCDetails -Xloggc:ListAddThreads_more_gc.log ListAddThreads more  2>nul
Array List:
Sum: 199999990000000, time: 48
Sum: 199999990000000, time: 56
Sum: 199999990000000, time: 39

Linked List:
Sum: 199999990000000, time: 108
Sum: 199999990000000, time: 93
Sum: 199999990000000, time: 94

java -Xms4G -Xmx4G -XX:+PrintGCDetails -Xloggc:ListAddThreads_lots_gc.log ListAddThreads lots  2>nul
Array List:
Sum: 199999990000000, time: 52
Sum: 199999990000000, time: 68
Sum: 199999990000000, time: 39

Linked List:
Sum: 199999990000000, time: 115
Sum: 199999990000000, time: 89
Sum: 199999990000000, time: 91