Spec-Zone.ru › Octave 6

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–2022 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/v6.4.0/Miscellaneous-Techniques.html

Spec-Zone.ru

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