Spec-Zone.ru › Octave 9

19.6 Различные приемы

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

  • Избегайте многократного вычисления дорогостоящих промежуточных результатов. В настоящее время Octave не устраняет общие подвыражения. Кроме того, некоторые результаты внутренних вычислений кэшируются для переменных. Например, если матричная переменная используется в качестве индекса несколько раз, проверка индексов (и внутреннее преобразование в целые числа) выполняется только один раз.
  • Помните о ленивом копировании (копировании при записи). При создании копии объекта данные не копируются сразу, а совместно используются. Фактическое копирование откладывается до тех пор, пока не потребуется изменить скопированные данные. Например:
    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–2026 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.4.0/Miscellaneous-Techniques.html

Spec-Zone.ru

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