Почему один stream быстрее, чем multithreading в Java?

Насколько я понимаю, я написал простую однопользовательскую и многопоточную программу ниже, чтобы проверить скорость выполнения. Но моя однопоточная программа выполняется быстрее, чем multithreading, любезно см. Ниже программу и упоминает, что что-то не так.

Одиночная тема:

import java.util.Calendar; public class NormalJava { public static void main(String[] args) { System.out.println("Single Thread"); int a = 1000; int b = 200; NormalJava nj = new NormalJava(); nj.Add(a, b); nj.Sub(a, b); nj.Mul(a, b); nj.Div(a, b); Calendar lCDateTime = Calendar.getInstance(); System.out.println("Calender - Time in milliseconds :" + lCDateTime.getTimeInMillis()); } private void Add(int a, int b) { System.out.println("Add :::" + (a + b)); } private void Sub(int a, int b) { System.out.println("Sub :::" + (a - b)); } private void Mul(int a, int b) { System.out.println("Mul :::" + (a * b)); } private void Div(int a, int b) { System.out.println("Mul :::" + (a / b)); } } 

Вывод:
Отдельная тема
Добавить ::: 1200
Sub ::: 800
Mul ::: 200000
Мул ::: 5
Calender – Время в миллисекундах: 138 415 866 7863

Многопоточная программа:

 package runnableandcallable; import java.util.ArrayList; import java.util.Calendar; import java.util.List; import java.util.concurrent.Callable; import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; public class MainThread { private static ExecutorService service = Executors.newFixedThreadPool(10); // connection // pool @SuppressWarnings("unchecked") public static void main(String[] args) throws InterruptedException { System.out.println("Multithreading"); MainThread mt = new MainThread(); mt.testThread(1000, 200); Calendar lCDateTime = Calendar.getInstance(); System.out.println("Calender - Time in milliseconds :" + lCDateTime.getTimeInMillis()); } public void testThread(final int a, final int b) { // create a callable for each method Callable callableAdd = new Callable() { @Override public Void call() throws Exception { Add(a, b); return null; } }; Callable callableSub = new Callable() { @Override public Void call() throws Exception { Sub(a, b); return null; } }; Callable callableMul = new Callable() { @Override public Void call() throws Exception { Mul(a, b); return null; } }; Callable callableDiv = new Callable() { @Override public Void call() throws Exception { Div(a, b); return null; } }; // add to a list List<Callable> taskList = new ArrayList<Callable>(); taskList.add(callableAdd); taskList.add(callableSub); taskList.add(callableMul); taskList.add(callableDiv); // create a pool executor with 3 threads ExecutorService executor = Executors.newFixedThreadPool(3); try { // start the threads List<Future> futureList = executor.invokeAll(taskList); for (Future voidFuture : futureList) { try { // check the status of each future. get will block until the // task // completes or the time expires voidFuture.get(100, TimeUnit.MILLISECONDS); } catch (ExecutionException e) { System.err .println("Error executing task " + e.getMessage()); } catch (TimeoutException e) { System.err.println("Timed out executing task" + e.getMessage()); } } } catch (InterruptedException ie) { // do something if you care about interruption; } } private void Add(int a, int b) { System.out.println("Add :::" + (a + b)); } private void Sub(int a, int b) { System.out.println("Sub :::" + (a - b)); } private void Mul(int a, int b) { System.out.println("Multiply :::" + (a * b)); } private void Div(int a, int b) { System.out.println("Division :::" + (a / b)); } } 

Mulithreading Output:
Многопоточность
Sub ::: 800
Отдел ::: 5
Добавить ::: 1200
Multiply ::: 200000
Calender – Время в миллисекундах: 138 415 868 0821

Здесь один stream выполняется на 138 415 866 7863 миллисекундах и multithreading, выполненная на этом 138 415 868 0821 миллисекундах. Тогда какова истинная цель многопоточности?

Обработка, которую вы делаете, тривиальна, поэтому накладные расходы на создание streamов более дороги.

Если у вас были дорогостоящие операции, которые можно было выполнить параллельно, то multithreading имеет смысл.

Во-первых : поскольку накладные расходы на создание streamов больше, чем полезная работа, выполняемая ими. Если вы выполняете более сложную работу в streamах, она будет работать быстрее, чем один stream. Типичный код должен быть запущен в одном streamе.

Второе : для создания микро-бенчмарка вы должны использовать JMH

1,384,158,667,863 миллисекунды – около 44 лет. Итак, вы говорите нам, что вы ожидали 44 года от результата этой операции? Или может быть что-то не так с тем, как вы измеряете скорость исполнения?

Чтобы измерить разницу в два раза, вам нужно как минимум два раза, в то время как вы получаете только текущую дату в конце своей программы, которая даже не близка к точной.

Простой измерительный class:

 public class StopWatch { private long startTime = -1; public void start() { this.startTime = System.nanoTime(); } public long timeNanos() { return System.nanoTime() - this.startTime; } public double timeMillis() { return this.timeNanos() / 1000000.0; } } 

Используйте этот секундомер, чтобы измерить время выполнения (например, использовать секундомер), затем сделайте это 3 раза и поймите, что каждый раз, когда вы получаете совершенно разные результаты. Это связано с тем, что измерение точного времени выполнения вообще не является тривиальным. ОС постоянно прерывает выполнение вашей программы другими задачами, и, казалось бы, простые команды могут иметь целую цепочку фоновых команд, которые необходимо запустить.

Все, что вы можете сделать, это приблизительное время, затрачиваемое на выполнение этой задачи, как миллион раз, а затем принять среднее значение.

Прежде всего, ваше время в миллисекундах – это только метка времени. Вам нужна разница в милисекундах между до и после вызова, чтобы измерить прошедшее время. Я предполагаю, что сначала вы запускали однопоточное приложение. Если вы сначала попробуете запустить многопоточное приложение, вы заметите, что оно имеет более низкое значение «время в миллисекундах».

Во-вторых. Создание и управление streamами имеет накладные расходы, что намного выше, чем время выполнения самых простых арифметических операций, которые вы выполняете. Если вы попытаетесь выполнить итерацию операций несколько миллионов раз, вы можете увидеть прирост производительности, выполнив параллельные операции.

Если вы рассматриваете один процессор. Все streamи выполняются на одном процессоре. давайте предположим, что ваша программа (jvm) имеет время выполнения на процессоре с частотой в 0.2 сек каждую секунду. Если вы выполняете в одном streamе, 0,2 секунды будут выделены только для этого основного streamа. Если вы выполните его на 4 streamах, например, 0,2 секунды, вы не будете иметь 0,05 + 0,05 + 0,05 + 0,05. Вам нужно будет добавить дополнительное время для синхронизации, возобновления и удаления streamов. Если мы предположим, что эта операция занимает 0.001 секунды для каждого переключения контекста. Вы получаете 0,004 секунды времени выполнения, теряемого каждую секунду, при условии, что stream выполняется один раз в секунду. В реальной жизни переключение контекста streamа выполняется много раз в секунду, и это непредсказуемо. Теперь все меняется, так как многоядерные машины и streamи могут выполняться одновременно на разных ядрах.

Для получения дополнительной информации см. Эту ссылку: поддерживает ли Java многоядерные процессоры / параллельную обработку?

  • Блок ThreadPoolExecutor, когда очередь заполнена?
  • Выполнение функции в фоновом режиме при использовании ограниченного количества ядер / streamов и очереди дополнительных исполнений?
  • Создание streamов - Task.Factory.StartNew vs new Thread ()
  • Как приостановить / скрыть stream или процесс в Android?
  • Разница между wait () и sleep ()
  • Многопоточный и SIMD-векторизованный Mandelbrot в R с использованием Rcpp & OpenMP
  • Что было бы лучше для одновременных задач на node.js? Волwindows? Веб-рабочие? или Threads?
  • Преимущество использования Thread.Start vs QueueUserWorkItem
  • Является ли функция EndInvoke () опциональной, необязательной или необязательной?
  • Много процессов обрабатывают и записывают один файл
  • форматировать исключение бросания streamа "thread_resource_error: ресурс временно недоступен"
  • Interesting Posts

    Как получить annotations переменной-члена?

    jQuery читать stream AJAX постепенно?

    Прокручивать файлы в папке с помощью VBA?

    Как заставить Windows повторно подключать USB-устройство, не подключая его снова?

    Требуется уточнение для лирических идентификаторов Scala (backticks)

    Как определить, установлен ли iPhone для 12-часового или 24-часового отображения времени?

    Postgresql: лучше ли использовать несколько баз данных по 1 схеме или 1 базу данных с несколькими схемами?

    Пакетное разделение многих AVI на 2 части?

    Программа для обмена файлами между дисками?

    Вскрытие всплывающих окон доступа к устройствам USB?

    Поведение printf при печати% d без указания имени переменной

    NoClassDefFoundError com.apache.hadoop.fs.FSDataInputStream при выполнении искровой оболочки

    В чем разница между регулярной строкой и стенографической строкой?

    Загружать локальный HTML-файл в C # WebBrowser

    Установите Windows XP / 7 без дисковода компакт-дисков, когда BIOS не поддерживает загрузку с USB-устройств

    Давайте будем гением компьютера.