Spec-Zone.ru › Octave 9

Далее: Примеры, Предыдущее: Запоминание результатов, Вверх: Векторизация и ускорение выполнения кода [Оглавление][Индекс]

19.6 Разные приёмы ¶

Вот несколько других способов повышения скорости выполнения программ Octave.

  • Избегайте многократного вычисления дорогостоящих промежуточных результатов. Octave в настоящее время не устраняет общие подвыражения. Также некоторые внутренние результаты вычислений кэшируются для переменных. Например, если матричная переменная используется несколько раз в качестве индекса, проверка индексов (и внутреннее преобразование в целые числа) выполняется только один раз.
  • Учитывайте ленивые копии (copy-on-write). При создании копии объекта данные не копируются немедленно, а, скорее, разделяются. Фактическое копирование откладывается до тех пор, пока скопированные данные не потребуются для изменения. Например:
    a = zeros (1000); # create a 1000x1000 matrix
    b = a; # no copying done here
    b(1) = 1; # copying done here

    Ленивое копирование применяется к целым объектам Octave, таким как матрицы, массивы ячеек, структуры, а также к отдельным элементам массивов ячеек или структур (не элементам массивов).

    Кроме того, выражения индексации также используют ленивое копирование, когда Octave может определить, что индексированная часть непрерывна в памяти. Например:

    a = zeros (1000); # create a 1000x1000 matrix
    b = a(:,10:100);  # no copying done here
    b = a(10:100,:);  # copying done here

    Это относится к массивам (матрицам), массивам ячеек и структурам, индексированным с помощью «()». Выражения индексации, генерирующие списки через запятые, также могут в некоторых случаях извлечь выгоду из поверхностного копирования. В частности, когда a — массив структур, выражения, такие как {a.x}, {a(:,2).x} будут использовать ленивое копирование, чтобы данные можно было разделить между массивом структур и массивом ячеек.

    Большинство выражений индексации существуют не дольше, чем их родительские объекты. Однако в редких случаях лениво скопированный срез переживает свой родительский объект, в результате чего он становится «сиротой», всё ещё занимая ненужно больше памяти, чем требуется. Чтобы предложить решение, работающее в большинстве реальных случаев, Octave проверяет на наличие «сирот» (лениво скопированных срезов) в определённых ситуациях, когда значение хранится в «постоянном» месте, таком как именованная переменная или элемент массива ячеек или структуры, и возможно оптимизирует их. Например:

    a = zeros (1000); # create a 1000x1000 matrix
    b = a(:,10:100);  # lazy slice
    a = []; # the original "a" array is still allocated
    c{1} = b; # b is reallocated at this point
  • Избегайте глубокой рекурсии. Вызовы функций m-файлов несут относительно значительные накладные расходы, поэтому переписывание рекурсии в цикл часто помогает. Также обратите внимание на ограничение максимального уровня рекурсии.
  • Избегайте ненужного изменения размера матриц. При построении единой результирующей матрицы из серии вычислений сначала задайте размер результирующей матрицы, а затем вставьте в неё значения. Напишите
    result = zeros (big_n, big_m)
    for i = over:and_over
      ridx = ...
      cidx = ...
      result(ridx, cidx) = new_value ();
    endfor

    вместо

    result = [];
    for i = ever:and_ever
      result = [ result, new_value() ];
    endfor

    Иногда количество элементов нельзя вычислить заранее, и необходимы стекообразные операции. Когда элементы неоднократно вставляются или удаляются с конца массива, Octave распознаёт это как использование стека и пытается применить более разумную стратегию управления памятью, предварительно выделяя массив большими кусками. Эта стратегия также применяется к массивам ячеек и структур.

    a = [];
    while (condition)
      ...
      a(end+1) = value; # "push" operation
      ...
      a(end) = []; # "pop" operation
      ...
    endwhile
  • Избегайте чрезмерного вызова eval или feval. Парсинг входных данных или поиск имени функции в таблице символов являются относительно дорогостоящими операциями.

    Если вы используете eval только как механизм обработки исключений, а не потому, что вам нужно выполнить произвольный текст, используйте оператор try вместо этого. См. Оператор try.

  • Используйте ignore_function_time_stamp при необходимости. Если вы вызываете много функций, и ни одна из них не должна меняться во время выполнения, установите переменную ignore_function_time_stamp в "all". Это предотвратит проверку Octave отметки времени файла функции, чтобы увидеть, была ли она обновлена во время выполнения программы.

Далее: Примеры, Предыдущее: Запоминание результатов, Вверх: Векторизация и ускорение выполнения кода [Оглавление][Индекс]

© 1996–2023 The Octave Project Developers
Permission is granted to make and distribute verbatim copies of this manual provided the copyright notice and this permission notice are preserved on all copies.
Permission is granted to copy and distribute modified versions of this manual under the conditions for verbatim copying, provided that the entire resulting derived work is distributed under the terms of a permission notice identical to this one.
Permission is granted to copy and distribute translations of this manual into another language, under the above conditions for modified versions.
https://docs.octave.org/v9.2.0/Miscellaneous-Techniques.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API