Форма Грузится Долго

Тема в разделе "Lotus - Программирование", создана пользователем Chron, 29 мар 2012.

  1. Chron

    Chron Well-Known Member

    Регистрация:
    16 авг 2010
    Сообщения:
    49
    Симпатии:
    0
    Всем привет... У меня небольшая проблемка возникла (ну как небольшая, меня лично изрядно напрягает).... в общем, существует база... в нее ломяться как из внутренней сети напрямую, так и из подразделений через модемы, випнет координаторы и т.п. Дело в том, что у тех, кто сидит внутри сети проблем с базой нет, а у внешних пользователей они есть... а именно то, что долго грузится одна форма... проверял дебагером, логика заступоривается именно на диалогбоксе, которая собственно говоря эту форму вызывает... примерно две минуты виснет прежде, чем вывести форму... возможны конечно варианты со скоростью, но согласитесь задержка в 30 мс вряд ли позволит являться форме целых две минуты... И хотелось бы совета, может есть какие-то лотус-утилиты, которые позволяет отследить в каком месте форма так долго загружается... возможно я как-то ее оптимизирую, или возможно вы сами что-нибудь мне предложите, если сталкивались с подобным... Спасибо...
     
  2. savl

    savl Lotus team
    Lotus team

    Регистрация:
    28 окт 2011
    Сообщения:
    2.051
    Симпатии:
    146
    На той форме много вычисляемых полей?
    Я конечно не силен, но такое ощущение, что форма, как раз, все эти поля высчитывает долго.

    Если есть возможность открой форму без dialogbox, посмотри сколько грузиться.
    Без dialogbox поможет легкий таймер.

    Делаешь в событиях формы:
    Код (LotusScript):
    Declarations:
    Dim dtB as NotesDateTime
    Dim dtE as NotesDateTime

    Initialize:
    set dtB = new NotesDateTime("")
    set dtE = new NotesDateTime("")
    call dtB.SetNow()

    PostOpen:
    call dtE.SetNow()

    msgbox "" & dtE.TimeDifference(dtB) 'Время в секундах
    Как ты понимаешь, тебе откроется message со временем открытия.

    А как ты форму диалога вызвываешь и для чего?

    Через script или на собаках?
    Для заполнения или отображения информации просто?
     
  3. Chron

    Chron Well-Known Member

    Регистрация:
    16 авг 2010
    Сообщения:
    49
    Симпатии:
    0
    savl, на скрипте вызывается... время вызова без диалогбокса такое же... я тут проверил, в итоге долго отрабатывается вот этот цикл:
    Код (LotusScript):
    Set viewAD = b.GetView("($VIMGroups)") ' доступ к виду с Группами  
    Set docAD = viewAD.GetFirstDocument ' к первому документу вида Группы

    Do While Not docAD Is Nothing ' проверяем все документы вида Группы
    ListGroup = docAD.Members              
    Forall ii In ListGroup
    If nameS.Canonical = ii Then
    ' создаем список групп, в которых активный юзер является членом                    
    If      Iselement ( ListGroupStr ( docAD.ListName(0) ) ) Then
    Else
    ListGroupStr(docAD.ListName(0)) = 0                            
    End If
    Else
    End If
    End Forall
    Set docAD = viewAD.GetNextDocument(docAD)  
    Loop
    End If
    End Forall
    Возможно его как-то оптимизировать?

    Следует отметить, что дочерних серверов много, а адресная книга общая... и там групп мерено-немерено просто...
     
  4. turumbay

    Регистрация:
    13 мар 2009
    Сообщения:
    625
    Симпатии:
    2
    А к чему там последний Forall? У вас есть еще и внешний цикл???
    Для начала - стоит поменять местами внешний и внутренний циклы( если конечно внешний не по списку баз ). Приведите код целиком.

    Откуда берутся names? Я так понимаю, что это не текущий пользователь, а некоторое произвольное нотес-имя?
    Какую задачу решает код?
     
  5. FixeR

    FixeR Гость

    ListGroupStr - насколько я понял, это list, список групп, в которых состоит пользователь.

    Chron,
    Если это так, то Вам нужна функция @UserNamesList.
     
  6. savl

    savl Lotus team
    Lotus team

    Регистрация:
    28 окт 2011
    Сообщения:
    2.051
    Симпатии:
    146
    Если действительно нужно получить просто список групп, в которых состоит пользователь, то я соглашусь с FixeR. Эта функция его выдаст, так же есть аналог на скрипте: NotesSession.UserGroupNameList
    Но за аналогичность работы не ручаюсь, надо проверить.
     
  7. turumbay

    Регистрация:
    13 мар 2009
    Сообщения:
    625
    Симпатии:
    2
    Вопрос был не "что делает?", а "зачем делает?". Если бы автор рассказал, какую задачу решает - то можно было бы подумать над альтернативными способами прохождения квеста.
    Смущает хвост от некоего внешнего цикла - есть подозрение, что группы разворачиваются не для текущего юзера, а для некоего списка notes-имен(т.е. UserGroupNameList не катит) . Если предположение верно - то самая очевидная оптимизация - вывернуть циклы наизнанку и итерировать вьюху ровно один раз. Кроме того, можно попробовать заменить клиентский поиск на серверный, т.е. вместо обхода всей вьюхи юзать db.search. Дальше можно думать о кешировании результатов функции, например в профайле. В общем вариантов масса, но нужно понимать контекст задачи....
     
  8. Chron

    Chron Well-Known Member

    Регистрация:
    16 авг 2010
    Сообщения:
    49
    Симпатии:
    0
    Привожу полный кусок кода...
    Код (LotusScript):
    books = session.AddressBooks ' получаем доступ ко всем адресным книгам на текущем сервере
    Forall b In books
    If b.IsPublicAddressBook Then
    Call b.Open( "", "" )

    Set viewAD = b.GetView("($VIMGroups)") ' доступ к виду с Группами  
    Set docAD = viewAD.GetFirstDocument ' к первому документу вида Группы

    Do While Not docAD Is Nothing ' проверяем все документы вида Группы
    ListGroup = docAD.Members              
    Forall ii In ListGroup
    If nameS.Canonical = ii Then
    ' создаем список групп, в которых активный юзер является членом                    
    If      Iselement ( ListGroupStr ( docAD.ListName(0) ) ) Then
    Else
    ListGroupStr(docAD.ListName(0)) = 0                            
    End If
    Else
    End If
    End Forall
    Set docAD = viewAD.GetNextDocument(docAD)  
    Loop
    End If
    End Forall
     
  9. savl

    savl Lotus team
    Lotus team

    Регистрация:
    28 окт 2011
    Сообщения:
    2.051
    Симпатии:
    146
    Думаю, что можно заменить этот Forall

    Код (LotusScript):
                  Forall ii In ListGroup
    If nameS.Canonical = ii Then
    ' создаем список групп, в которых активный юзер является членом                    
    If       Iselement ( ListGroupStr ( docAD.ListName(0) ) ) Then
    Else
    ListGroupStr(docAD.ListName(0)) = 0                            
    End If
    Else
    End If
    End Forall
    на

    Код (LotusScript):
    k = ArrayGetIndex(ListGroup,nameS.Canonical)
    if no Isnull(k) then
    If Not Iselement ( ListGroupStr ( docAD.ListName(0) ) ) Then
    ListGroupStr(docAD.ListName(0)) = 0                            
    End If
    end if
    своеобразное ускорение даст, так как перебора имен не будет.
    Но это для текущей сессии работает, так что можно попробывать UserGroupNameList и сравнит результаты.
     
  10. nvyush

    nvyush Lotus team
    Lotus team

    Регистрация:
    22 апр 2009
    Сообщения:
    2.317
    Симпатии:
    0
    Chron
    Некоторого (небольшого) ускорения можно добиться, заменив
    Код (LotusScript):
    Do While Not docAD Is Nothing
    на
    Код (LotusScript):
    Do Until docAD Is Nothing
    А конструкция
    Код (LotusScript):
            If b.IsPublicAddressBook Then
    Call b.Open( "", "" )
    разве работает? Если верить справке, то "The database must be open to use this property" (свойство IsPublicAddressBook)
    Examples: IsPublicAddressBook property
    Код (LotusScript):
     Forall db In session.AddressBooks
    Call db.open("", "") ' Must open database
    If db.IsPublicAddressBook Then
    '...
     
  11. Chron

    Chron Well-Known Member

    Регистрация:
    16 авг 2010
    Сообщения:
    49
    Симпатии:
    0
    Быстрее работать к сожадению не стал...
    В случае с UserGroupNameList
    Код (LotusScript):
    ListGroupStr = session.UserGroupNameList
    и этого достаточно?
     
  12. nvyush

    nvyush Lotus team
    Lotus team

    Регистрация:
    22 апр 2009
    Сообщения:
    2.317
    Симпатии:
    0
  13. Мыш

    Мыш Lotus team
    Lotus team

    Регистрация:
    12 фев 2008
    Сообщения:
    1.019
    Симпатии:
    8
    Пардон, а сам Evaluate разве не есть источник тормозов?
     
  14. nvyush

    nvyush Lotus team
    Lotus team

    Регистрация:
    22 апр 2009
    Сообщения:
    2.317
    Симпатии:
    0
    Если аргумент Evaluate — строковая константа (как в данном случае), то формула компилируется на этапе компиляции скрипта и тормозов меньше.
     
  15. turumbay

    Регистрация:
    13 мар 2009
    Сообщения:
    625
    Симпатии:
    2
    и не будет быстрее. Вам предлагают оптимизацию того, что в оптимизации не нуждается: тюнить обращение к списку (который в памяти) смысла нет. Щаз кто-нить еще расскажет про оптимизацию расширенного синтаксиса и повсеместный переход на doc.getItemValue :)

    У вас проблема в том, что вы каждый раз скачиваете на клиента адресную книгу. То тех пор, пока будет проход по всем документам Group всех АК - ничто вас не спасет.
    Еще раз: какую задачу-то решаете? Откуда nameS берется? Это текущий юзер или таки нет? Можно ли выделить небольшое множество значений nameS, для которых выполняется 80% всех вызовов?
     
  16. Chron

    Chron Well-Known Member

    Регистрация:
    16 авг 2010
    Сообщения:
    49
    Симпатии:
    0
    Код (LotusScript):
    Dim nameS As New NotesName (session.UserName)
     
  17. turumbay

    Регистрация:
    13 мар 2009
    Сообщения:
    625
    Симпатии:
    2
    тогда, как сказали ранее - session.UserGroupNameList вам в помощь
    P.S. а с учетом http://www-01.ibm.com/support/docview.wss?uid=swg21280034, правильное решение предложено nvy: groups = Evaluate("@UserNamesList")
     
  18. Omh

    Omh Lotus team
    Lotus team

    Регистрация:
    4 июл 2007
    Сообщения:
    2.210
    Симпатии:
    0
    Ну и если идёшь по view, то перед началом прохода взведи
    Код (LotusScript):
    view.AutoUpdate = False
    , после -
    Код (LotusScript):
    view.AutoUpdate = True
    . Очень сильно влияет на быстродействие.
     
  19. turumbay

    Регистрация:
    13 мар 2009
    Сообщения:
    625
    Симпатии:
    2
    По жизни - да, но не в данном случае. Здесь 99% времени выполнения - это получение вьюхи и документов ( getView и getNextDocument ) соотвественно.
    AutoUpdate особенно хорош, когда бежим по индексу вида и не читаем из него документы ( т.е. используя только ViewEntry )
     
  20. Chron

    Chron Well-Known Member

    Регистрация:
    16 авг 2010
    Сообщения:
    49
    Симпатии:
    0
    Слущайте... я тут глянул... файл names.nsf не проиндексирован... это может как-то повлиять на перебор вьюшки?
     
Загрузка...

Поделиться этой страницей