Как мы можем обнаружить, что присваивание переменной выполняется быстрее с помощью оператора assign по сравнению с другим методом? Пожалуйста, объясни.
Присвоение переменной, когда они сгруппированы с помощью assign
Ответы (3)
Конечно, это зависит от того, что именно вы присваиваете и сколько отдельных утверждений вы группируете вместе. Но простой пример сравнения разницы достаточно легко собрать:
define variable i as int64 no-undo.
define variable x1 as int64 no-undo.
define variable x2 as int64 no-undo.
define variable x3 as int64 no-undo.
define variable x4 as int64 no-undo.
define variable x5 as int64 no-undo.
etime( yes ).
do i = 1 to 10000:
assign
x1 = i
x2 = i
x3 = i
x4 = i
x5 = i
.
end.
message "with a grouped ASSIGN:" etime.
etime( yes ).
do i = 1 to 10000:
x1 = i.
x2 = i.
x3 = i.
x4 = i.
x5 = i.
end.
message "without ASSIGN:" etime.
ВНЕШНЯЯ ПОМОЩЬ:
На современном релизе Прогресса особой разницы я бы не увидел. Даже в бенчмарке, призванном показывать такие вещи. Довольно много вещей, которые были медленными и нуждались в оптимизации 30 лет назад, больше не нуждаются в такой микрооптимизации.
Я ожидаю, что любую разницу, которая все еще существует, еще труднее найти в реалистичном коде. (Приведенный выше пример не очень реалистичен.) Конечно, вероятно, есть несколько конкретных случаев, когда это полезная оптимизация производительности. Но я бы не стал использовать производительность в качестве оправдания для этого. Ссылка, на которую указывает Остин - что такое эффективность оператора assign в progress-4gl дает более убедительные причины.
Просто выбрасываю этот бессмысленный тест, который как минимум вы должны были указать в своем вопросе, чтобы начать задавать что-то значимое, для дальнейшего обсуждения:
def var dt as datetime no-undo extent 4.
def var ic as int no-undo initial {&sequence}.
def var cc as char no-undo.
&scoped-define iterations 10000000
dt[{&sequence}] = now.
do ic = 1 to {&iterations}:
cc = "hello".
end.
dt[{&sequence}] = now.
cc = "".
dt[{&sequence}] = now.
do ic = 1 to {&iterations}:
assign cc = "hello".
end.
dt[{&sequence}] = now.
message
interval( dt[2], dt[1], "milliseconds" ) skip
interval( dt[4], dt[3], "milliseconds" )
.
https://abldojo.services.progress.com:443/#/?shareId=5ef603c34b1a0f40c34b8c63
Для 10 000 000 (десяти миллионов) итераций вышеприведенной ерунды версия с назначением занимает 2392 мс, а версия без назначения — 2469 мс — это экономия 77 миллисекунд — простая производительность не имеет значения и сильно перевешивается факторами, упомянутыми в статье Тома. более ранний ответ о читабельности и намерениях.
У вас /может/ быть случай, в котором это имеет значение, и в этом случае вам нужно будет провести собственное измерение.
Использование ключевого слова имеет много преимуществ, и вы определенно можете подробно прочитать здесь: https://documentation.progress.com/output/ua/OpenEdge_latest/index.html#page/dvref/assign-statement.html
Что касается моего личного опыта, я могу сказать следующее: у меня нет тестов, чтобы убедиться, что они на самом деле быстрее, но я бы сказал, что преимущества использования оператора ASSIGN больше связаны с управлением транзакциями/поведением. С оператором assign вы можете, например, использовать опцию NO-ERROR, которая позволяет обрабатывать возможные проблемы с используемыми вами значениями.
Я бы сказал, что это также вопрос эстетики языка. Однострочные назначения без ключевого слова сделают эту работу. Но это, вероятно, будет выглядеть неряшливо.