Lotus Script: взгляд изнутри

ToxaRat

Чёрный маг
Green Team
06.11.2007
3 332
42
BIT
0
nvy
когда компилятор додумаетя вместо вызова функций сразу жарить константы(это полный перебор типа) это будет ващще круть :)
прикинте у вас офигенный код, а компилятор сразу жарит на выходе 12 одним байтом кода, так как он всё перебрал и учел что будет токо так ;)
 
A

Akupaka

когда компилятор додумаетя вместо вызова функций сразу жарить константы(это полный перебор типа)
Что это такое ты имел в виду за переборы? :)

Вообще-то логично предположить таковую оптимизацию работы компилятора, т.к. формируется символ из первой части таблицы, которая уже много лет не меняется.
Другое дело, есть ли смысл на этом заморачиваться?..
 

lmike

нет, пердело совершенство
Lotus Team
27.08.2008
7 983
611
BIT
453
уже упоминал - ИБМ не занимается развитием LS
в др. языках есть статики, кот. инициализируются "в начале"
а конетктация строк, в LS, обсуждалась выше - она и так... "не оптимальна"
 
A

Akupaka

Нотес-ляп :rolleyes:
Если в каком-либо поле LS-обработчик события Onchange переименовать в OnChange или OnchAnge, то он не сработает, хотя LS case insensitive
 
30.06.2006
141
5
BIT
0
IBM говорит что получение сессии и текущей базы данных - это очень быстрые операции.

Есть подозрения, что когда запускается обработчик LotusScript'а (запуск агента или вызов функции из библиотеки), то где-то в глубине создается скрытый глобальный объект NotesSession (и NotesDatabase), который освобождается только при завершении работы обработчика LotusScript'а.

Тогда получается, что при инициализации в коде переменных типа NotesSession (Set session = New NotesSession) происходит всего лишь присвоение ссылки на глобальный объект сессии, поэтому эта операция выполняется быстро.

И также - что все объекты, полученные от переменных типа NotesSession в коде продолжают существовать, т.к. их родитель на самом деле - скрытый глобальный объект сессии, который живет до окончания всего кода.

P.S.
Это всего лишь предположение.
 

savl

Lotus Team
28.10.2011
2 624
314
BIT
517
читал, что NotesSession и NotesUIWorkspace являются статическими объектами. Теперь бы вспомнить где...

Нашел:
Don't Worry About NotesSession Objects
Don't worry about using:

Dim session as New NotesSession
Set db = session.CurrentDatabase

in several places in your agents. The NotesSession and CurrentDatabase objects are static, so you can make those two calls as often as you'd like within your code without the performance penalty of creating a new object.

источник:
 
A

ABarmin

Как вариант, можно сделать глобальную-функцию синглтон для обращения к сессии чтобы уж точно быть уверенным, что объект не меняется.
 

VladSh

начинающий
Lotus Team
11.12.2009
1 797
158
BIT
232
У меня просто глобальная переменная.
 

savl

Lotus Team
28.10.2011
2 624
314
BIT
517
Столкнулся тут с забавно фичей, которая наверняка всем известна, а я вот не знал) Но поделится наблюдениями хочется.
В коде кнопки на форме есть строка:
Код:
Set Doc = ws.CurrentDocument.Document
Если открыть документ (док-А), затем начать писать письмо из почты и не закрыв/не отправив его, переключиться на этот док-А.
Нажать данную кнопку, то в переменную Doc запишется ваше письмо из почты.
Будто объект ws ловит письмо как документ с высшим приоритетом. Есть идеи что это за магия?)
 

VladSh

начинающий
Lotus Team
11.12.2009
1 797
158
BIT
232
Если открыть документ (док-А), затем начать писать письмо из почты и не закрыв/не отправив его, переключиться на этот док-А.
Нажать данную кнопку, то в переменную Doc запишется ваше письмо из почты.
Эта баго-фича всегда была, даже где-то здесь было обсуждение...
На событиях формы, кнопках и действиях надо пользоваться документом, полученным из Source (NotesUIDocument) в одном из событий открытия документа.
 

savl

Lotus Team
28.10.2011
2 624
314
BIT
517
Угу, если если в PO определен, то все ок.
Это вот за правило надо взять, что объекты (UI и не UI) документа определятся должен в PO.
Особенно начинающим, работать проще с доком будет.
 

savl

Lotus Team
28.10.2011
2 624
314
BIT
517
кстати у товарища возникла такая же проблема, но в агенте, который запускается по кнопке. Причем как из вьюшки, так и из формы.
Как грамотнее обойти?
Я пока кроме получения ws.CurrentView ничего не придумал...
То есть сначала определяем текущий вид, если его нет - значит в документе, а если есть - значит во вьюшке...
 
N

nvyush

И перестал бы делать такие проверки:

Код:
If CurDoc.old_number(0)<>"" Then
так гораздо лучше:

Код:
If Len(ndCurrent.getItemValue("ItemName")(0)) <> 0 Then
Тесты в студию! Для java, javascript согласен, но для lotusscript вызывает сомнение.
Добавлено
<div class="sp-wrap"><div class="sp-head-wrap"><div class="sp-head folded clickable">Я тестировал таким агентом:</div></div><div class="sp-body"><div class="sp-content">
Код:
(Declarations)
Dim TICKS_PER_SEC As Long
Sub Initialize
TICKS_PER_SEC = Getthreadinfo(7)
test_String_Compare
End Sub
Sub test_String_Compare
'данный тест сравнивает явное сравнение строки с пустой строкой и проверку длины строки
Const count = 1000000
Print Cstr(Now) + ": " + Cstr(Getthreadinfo(1)) + ":"
Call test_String_Compare_EqualsString(count)
Call test_String_Compare_EqualsLen(count)
Call test_String_Compare_EqualsString(count)
Call test_String_Compare_EqualsLen(count)
Call test_String_Compare_EqualsString(count)
Call test_String_Compare_EqualsLen(count)
Call test_String_Compare_EqualsString(count)
Call test_String_Compare_EqualsLen(count)
Call test_String_Compare_EqualsString(count)
Call test_String_Compare_EqualsLen(count)
End Sub
Sub test_String_Compare_EqualsString(count As Long)
Dim v As Variant
Dim startTime As Double
Dim endTime As Double
Dim i As Long
Dim bool As Boolean
Dim s As String
s = "dfartethwrghdgsdgas"
startTime = Getthreadinfo(6)
For i = 0 To count
bool = (s = "")
Next
endTime = Getthreadinfo(6)
Print Cstr(Getthreadinfo(1)) & ". Timer = " & Format((endTime - startTime) / TICKS_PER_SEC, "0.000") & " s"
End Sub
Sub test_String_Compare_EqualsLen(count As Long)
Dim v As Variant
Dim startTime As Double
Dim endTime As Double
Dim i As Long
Dim bool As Boolean
Dim s As String
s = "dfartethwrghdgsdgas"
startTime = Getthreadinfo(6)
For i = 0 To count
bool = (Len(s) = 0)
Next
endTime = Getthreadinfo(6)
Print Cstr(Getthreadinfo(1)) & ". Timer = " & Format((endTime - startTime) / TICKS_PER_SEC, "0.000") & " s"
End Sub
 

lmike

нет, пердело совершенство
Lotus Team
27.08.2008
7 983
611
BIT
453
значит так я мыслю...
сравнение с пустой строкой - вызовет дополнительную генерацию объекта строки, что "накладно по памяти", причем не фак что объект будет повторно использован, но такой стиль "не поощряется" (в объектных языках)
если уж тестировать - надо было циклическим вызовом агента (чтобы был сборщик и инициализация объектов)
и писать <>0 как-то "неэстетично" :( - >0
 
N

nvyush

если уж тестировать - надо было циклическим вызовом агента (чтобы был сборщик и инициализация объектов)
В этом случае будет сравниваться время выполнения кучи "лишнего" кода, причем время старта агента, инициализации переменных и сборки мусора будет существенно больше времени выполнения операции сравнения. Вес брутто будет на порядки больше веса нетто.
 

VladSh

начинающий
Lotus Team
11.12.2009
1 797
158
BIT
232
Адрес студии?
Пока адреса нет, напишу сюда.

Тестировал Вашим же кодом.
Что сделал:
1. Разбил код на 2 агента, в каждый из которых выделил чисто его код со счётчиком. Функция в агенте вызывается единожды.
2. На всякий случай отключил антивирус.

Методика:
1. Вызов утилиты по очистке ОЗУ, открытие БД, запуск агента-1, запись результата, закрытие БД.
2. Вызов утилиты по очистке ОЗУ, открытие БД, запуск агента-2, запись результата, закрытие БД.
и так циклически.

Результаты (только min и max):
Код:
Equal = 0.437
Len  = 0.406
Equal = 0.422
Len  = 0.406
Остальные результаты по Equal лежат в промежутке 0.422-0.437, результат по Len всегда равен 0.406.

WinXP sp3 (32-bit) Ru корпоративная со всеми последними обновлениями; LN Release 8.5.3, без FP.
 

lmike

нет, пердело совершенство
Lotus Team
27.08.2008
7 983
611
BIT
453
В этом случае будет сравниваться время выполнения кучи "лишнего" кода, причем время старта агента, инициализации переменных и сборки мусора будет существенно больше времени выполнения операции сравнения. Вес брутто будет на порядки больше веса нетто.
зато будет учтен именно важный фактор различия
цель - заставить работать инициализацию и сборщик
можно попробовать рекурсивный вызов
"в жизни" именно такой сценарий и создает основную нагрузку на память и проц, а ваша методика уж очень теортическая
вот и VladSh сделал "похожий на жизнь" вариант тестирования
 

VladSh

начинающий
Lotus Team
11.12.2009
1 797
158
BIT
232
и писать <>0 как-то "неэстетично" :( - >0
Всегда считал, что проверка на неравенство выполняется быстрее, чем 'больше' или 'меньше'.

Изменил вышеуказанные агенты на проверку неравенства и добавил один для проверки на >.

Получились интересные результаты:

Агент сравнения Len() <> 0 выполняется либо за 0.406 либо за 0.422, причём это случается через раз, хотя прохожу всех трёх агентов по порядку. Изменял порядок, иногда получаются результаты 0.407 либо за 0.421, причём тоже через раз.

Агент сравнения Len() > 0 выполняется всегда за 0.406, независимо от порядка выполнения.

Агент сравнения Строка <> "" выполняется всегда за 0.438, независимо от порядка выполнения.
 
Мы в соцсетях:

Обучение наступательной кибербезопасности в игровой форме. Начать игру!