современный для цикла для примитивного массива

Во-первых, лучше всего указывать свой код в виде текста в уценке кода (старайтесь избегать скриншотов кода).

Что касается вашего вопроса, в этом руководстве по OpenCV это объясняется очень подробно. Примечательно, что сначала вам нужно найти контуры с помощью функции cv2.findContours, а затем нарисовать их с помощью cv2.drawContours следующим образом:

import numpy as np
import cv2
im = cv2.imread('test.jpg')
imgray = cv2.cvtColor(im, cv2.COLOR_BGR2GRAY)
ret, thresh = cv2.threshold(imgray, 127, 255, 0)
im2, contours, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)

где thresh - это ваше пороговое изображение.

13
задан Ann Kilzer 29 April 2015 в 21:34
поделиться

5 ответов

Ваша рукописная, "старая" форма выполняет меньше инструкций и может быть быстрее, хотя необходимо было бы представить ее в соответствии с данным JIT-компилятором для знания наверняка. "Новая" форма определенно не быстрее.

При рассмотрении демонтированного кода (скомпилированный JDK 1.5 Sun), Вы будете видеть, что "новая" форма эквивалентна следующему коду:

1: double[] tmp = doubleArray;
2: for (int i = 0, y = tmp.length; i < y; i++) {
3:   double var = tmp[i];
4:   someComplexCalculation(var);
5: }

Так, Вы видите, что используется больше локальных переменных. Присвоение doubleArray кому: tmp в строке 1 "дополнительно", но она не происходит в цикле и вероятно не может измеряться. Присвоение на var в строке 3 также дополнительно. Если бы существует разница в производительности, это было бы ответственно.

Строка 1 могла бы казаться ненужной, но это - шаблон для кэширования результата, если массив вычисляется методом прежде, чем ввести цикл.

Тем не менее я использовал бы новую форму, если Вы не должны делать что-то с индексной переменной. Любое различие в производительности, вероятно, будет оптимизировано далеко JIT-компилятором во времени выполнения, и новая форма более ясна. Если Вы продолжаете делать это "вручную", можно пропустить будущую оптимизацию. Обычно хороший компилятор может оптимизировать "глупый" код хорошо, но задержки на "умном" коде.

4
ответ дан 2 December 2019 в 00:47
поделиться

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

Были изученные "Шаблоны" людей времен, которые, казалось, оптимизировали некоторую операцию, но в следующей версии Java те шаблоны были на самом деле медленнее.

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

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

Как раз вовремя компиляция средств, это может иногда превосходить C по характеристикам, и нет никакой причины, это не может превзойти статический ассемблер по характеристикам в некоторых случаях (блок не может решить заранее, что вызов не требуется, Java может время от времени делать просто это.

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

5
ответ дан 2 December 2019 в 00:47
поделиться

Почему бы не измерить его самостоятельно?

Это звучит немного резким, но этот вид вопросов очень легок проверить себя.

Просто создайте массив и выполните каждый цикл 1000 или больше раз и измерьте количество времени. Повторитесь несколько раз для устранения незначительных сбоев.

2
ответ дан 2 December 2019 в 00:47
поделиться

Нет никакого различия. Java преобразует расширенное для в нормальное для цикла. Расширенным для является просто "сахар синтаксиса". Сгенерированный байт-код является тем же для обоих циклов.

1
ответ дан 2 December 2019 в 00:47
поделиться

Я стал очень любопытным на предмет Вашего вопроса, даже после моего предыдущего ответа. Таким образом, я решил проверить его сам также. Я записал эту маленькую часть кода (проигнорируйте математическую правильность о проверке, если число является простым ;-)):

public class TestEnhancedFor {

    public static void main(String args[]){
        new TestEnhancedFor();
    }

    public TestEnhancedFor(){
        int numberOfItems = 100000;
        double[] items = getArrayOfItems(numberOfItems);
        int repetitions = 0;
        long start, end;

        do {
            start = System.currentTimeMillis();
            doNormalFor(items);
            end = System.currentTimeMillis();
            System.out.printf("Normal For. Repetition %d: %d\n", 
                    repetitions, end-start);

            start = System.currentTimeMillis();
            doEnhancedFor(items);
            end = System.currentTimeMillis();
            System.out.printf("Enhanced For. Repetition %d: %d\n\n", 
                    repetitions, end-start);

        } while (++repetitions < 5);
    }

    private double[] getArrayOfItems(int numberOfItems){
        double[] items = new double[numberOfItems];
        for (int i=0; i < numberOfItems; i++)
            items[i] = i;
        return items;
    }

    private void doSomeComplexCalculation(double item){
        // check if item is prime number
        for (int i = 3; i < item / 2; i+=2){
            if ((item / i) == (int) (item / i)) break;
        }
    }

    private void doNormalFor(double[] items){
        for (int i = 0; i < items.length; i++)
            doSomeComplexCalculation(items[i]);
    }

    private void doEnhancedFor(double[] items){
        for (double item : items)
            doSomeComplexCalculation(item);
    }

}

Запущение приложения дало следующие результаты для меня:

Нормальный для. Повторение 0: 5 594 расширенных для. Повторение 0: 5594

Нормальный для. Повторение 1: 5 531 расширенный для. Повторение 1: 5547

Нормальный для. Повторение 2: 5 532 расширенных для. Повторение 2: 5578

Нормальный для. Повторение 3: 5 531 расширенный для. Повторение 3: 5531

Нормальный для. Повторение 4: 5 547 расширенных для. Повторение 4: 5532

Как мы видим, изменение среди результатов является очень маленьким, и иногда нормальный цикл работает быстрее, иногда расширенный цикл быстрее. С тех пор существуют другие приложения, открытые в моем компьютере, я нахожу это нормальным. Кроме того, только первое выполнение медленнее, чем другие - я полагаю, что это имеет отношение к оптимизации JIT.

Средние времена (исключая первое повторение) составляют 5535,25 мс для нормального цикла и 5 547 мс для расширенного цикла. Но мы видим, что лучшее время выполнения для обоих циклов - тот же (5 531 мс), таким образом, я думаю, что мы можем прийти к выводу, что оба цикла имеют ту же производительность - и изменения истекшего времени происходят из-за других приложений (даже ОС) машины.

1
ответ дан 2 December 2019 в 00:47
поделиться
Другие вопросы по тегам:

Похожие вопросы: