Почему назначение всего массива Blender происходит намного быстрее, чем назначение с помощью итерации?

#python #performance #blender

#python #Производительность #blender

Вопрос:

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

 def slow_random():
    for i in range(len(bpy.data.images['img'].pixels)):# < pixels are just a list of pixesl color values, where 0 <= value <= 1
        bpy.data.images['img'].pixels[i] = random()

def quick_random():
    rand = [random() for i in range(len(bpy.data.images['img'].pixels))]
    bpy.data.images['img'].pixels[0:] = rand
  

Вот ссылка на мой файл blend. Я не знаю, безопасно ли это. Я могу опубликовать аналогичный вопрос на BlenderStack и загрузить файл туда всего за 1,5 часа. загрузите, распакуйте и запустите blender отсюда (занимает минуты). Откройте файл, в окне скрипта вы можете нажать Alt P, чтобы запустить его. Раскомментируйте функции в конце списка. Функция slow просто заморозит приложение.

Я думаю, @cephner прав, говоря, что это связано с реализацией __setitem__ метода. Потому что он должен получить доступ к пикселю, изменить его значение и перерисовать его.

Комментарии:

1. Вы уверены, что выполняете тесты в надлежащих условиях? Эти два действия должны занять примерно одинаковое время. Вы также должны предоставить свой тестовый код.

2. @cglacet сделайте это за мгновение. хотя это в blender. Я больше нигде не использую python… Я прилагаю файл Blender и скрипт

3. Время для генерации случайных значений одинаковое. Однако, в зависимости от типа pixels атрибута, я могу представить, что назначение одного фрагмента может быть быстрее, чем назначение каждому элементу по отдельности. slow_random должен вызывать __setitem__ метод n типа несколько раз; quick_random должен вызывать его только один раз.

4. @cephner type(bpy.data.images['Untitled'].pixels) <class 'bpy_prop_array'> если я правильно понимаю, разработчики класса определили setitem для установки отдельных пикселей или всех пикселей сразу? Я имею в виду, что есть две разные реализации __setitme__ метода на C в зависимости от контекста? и __setitem__ для всего массива это сверхбыстрое?

5. Тогда вам следует задать вопрос об этом типе bpy_prop_array , потому что это несколько не связано с python (поскольку этот класс может реализовать что угодно и сделать этот код сверхмедленным).