Можно ли сделать отложенное выполнение в ASP? Или: пожалуйста, предложите любую помощь в улучшении производительности старого сайта ASP - PullRequest
4 голосов
/ 26 мая 2009

Я пытаюсь улучшить производительность сайта, написанного на классическом ASP.

Он поддерживает несколько языков, проблема заключается в том, как это было реализовано. Он имеет следующий метод:

GetTranslation(id,language)

Который называется по всему магазину так:

<%= GetTranslation([someid],[thelanguage]) %>

Этот метод просто ищет идентификатор и язык в SQL и возвращает перевод. Простой.

Но невероятно неэффективно. На каждой странице загружается около 300 независимых вызовов SQL для получения индивидуального перевода.

Я уже значительно улучшил производительность для многих сценариев:

  • Инструмент C #, который сканирует файлы .asp и выбирает ссылки на GetTranslation
  • Затем инструмент создает метод «объемного кэша», который (в зависимости от страницы) принимает все найденные им идентификаторы и одним махом кэширует результаты в словаре.
  • Затем метод GetTranslation был обновлен, чтобы проверять словарь на наличие любых запросов и обращаться к SQL, только если его там еще нет (и кэшировать свой собственный результат, если необходимо)

Это так далеко.

Когда идентификаторы переводов хранятся в базе данных, я не могу их забрать (особенно легко).

В идеале метод GetTranslation будет при каждом вызове создавать одну большую строку SQL, которая будет выполняться только в конце запроса страницы.

Возможно ли это в ASP? Можно ли получить результат <% = ...%>, который будет ссылкой на что-то, что будет позже разрешено?

Я также искренне оценил бы любые другие творческие способы, которыми я мог бы улучшить производительность этого старого, уродливого зверя.

Ответы [ 5 ]

2 голосов
/ 26 мая 2009

Я не думаю, что вы можете выполнять отложенное выполнение в Classic ASP. Что касается предложений по улучшению производительности. У вас может быть такой класс:

Class TranslationManager
        Private Sub Class_Initialize
        End Sub

        Private Sub Class_Terminate
        End Sub

        Private Function ExistsInCache(id, language)
            ExistsInCache = _
                Not IsEmpty(Application("Translation-" & id & "-" & language))
        End Function

        Private Function GetFromCache(id, language)
            GetFromCache = Application("Translation-" & id & "-" & language)
        End Function

        Private Function GetFromDB(id, language)
            //'GET THE RESULT FROM DB
            Application("Translation-" & id & "-" & language) = resultFromDB
            GetFromDB = resultFromDB
        End Function

        Public Default Function GetTranslation(id, language)
            If ExistsInCache(id, language) Then
                GetTranslation = GetFromCache(id, language)
            Else
                GetTranslation = GetFromDB(id, language)
            End If
        End Function
End Class

И используйте это в своем коде

Set tm = New TranslationManager
translatedValue = tm([someid], [thelanguage])
Set tm = Nothing

Это определенно уменьшит количество обращений к БД. Но вам нужно быть очень осторожным относительно того, сколько данных вы помещаете в объект приложения. Вы не хотите исчерпать память. Лучше всего также отслеживать, как долго переводы остаются в памяти и срок их действия истекает (удаляется из объекта приложения), если к ним в течение некоторого времени не обращались.

0 голосов
/ 28 мая 2009

Подход, который я использую в своей собственной CMS, заключается в загрузке всех статических строк языка из базы данных в объект приложения при запуске с использованием уникальных ключей на основе имени переменной, идентификатора языка и экземпляра CMS. Затем я использую кэширование на уровне страницы в массиве, поскольку страница создается так, что многократно используемая переменная кэшируется и по возможности избегает многократных обращений к объекту Application. Я использую массив вместо словаря в качестве способа, которым моя CMS-функция создает каждую страницу в разделах, причем каждый раздел изолирован от друг друга, поэтому я буду создавать несколько словарей на страницу, что нежелательно.

Очевидно, что жизнеспособность этого решения полностью зависит от количества ваших переменных и количества переводов, а также от того, сколько переменных вам нужно извлечь на каждой странице.

0 голосов
/ 26 мая 2009

Ваш кеш - лучшее сохранение, которое вы можете сделать здесь, вы можете покончить со сложностью пре-кэширования .net и просто делать каждый вызов GetTranslate проверять ваш словарь на предмет его ввода, если его там нет, он может получить его и кешировать его в пространстве приложения. Это было бы молниеносно. Тогда есть только проблема обновления кэша время от времени, но это будет выполняться для вас каждые 24 часа, когда рабочий процесс обновляется.

Если вам нужно, чтобы он был более свежим, чем этот, тогда вы можете получить все свои рекомендации, как вы делаете это с помощью .net cacher. Затем вы можете создать новую функцию, чтобы получить все записи для данного набора идентификаторов, написать вызов этой функции в верхней части ваших страниц ASP для каждой страницы, который будет вызывать вашу БД с одной строкой SQL, сохраняя результаты в виде местный словарь. Затем измените GetTranslation, чтобы использовать значения из этого словаря. Необходимо обновить, но это может быть частью вашего процесса сборки или просто работой, которая выполняется каждый час / ночь.

0 голосов
/ 26 мая 2009

Мы используем класс i18n с пространством имен и языковым атрибутом в нашей системе электронной коммерции. Класс имеет функцию по умолчанию, называемую «translate», которая в основном выполняет поиск в словаре. Этот словарь загружается с использованием шаблона memento из текстового файла, содержащего все переводы для пространства имен и языка.

Скелеты для этих файлов переводов создаются с помощью специального инструмента (фактически написанного на vbscript), который анализирует ASP для вызовов i18n ($ somestring). Имена файлов основаны на пространстве имен и языке, например, "Shoppingcart_step_1_FR.txt". Инструмент может фактически обновлять / расширять существующие файлы перевода, когда мы добавляем новые переводимые строки в код ASP, что очень важно для обслуживания.

Повышение производительности при использовании этого метода минимально. Благодаря сегментации наш самый большой файл перевода содержит около 200 переводимых строк (включая статические URL-адреса изображений). Загрузка его по запросу очень мало влияет на производительность. Я полагаю, что можно было бы кэшировать словари перевода в объекте приложения, используя какой-нибудь сторонний словарь TreadSafe, но ИМХО это не стоит проблем.

Дополнительный совет, используйте замену переменных в вашей строке, чтобы улучшить переводимость. Например, используйте:

  <%=replace(i18n("Buy $productname"), "$productname", product.name)%> 

вместо

  <%=i18n("Buy")%> <%=product.name%> 

Первый метод гораздо более гибкий для переводчиков. Многие языки имеют разные структуры предложений.

0 голосов
/ 26 мая 2009

<%= x %> просто переводится в Response.Write (x). Нет способа отложить это.

На самом деле, Classic ASP не имеет способа сделать что-либо отложенным, насколько я помню.

Вы уже многое сделали для написания инструмента кеширования. Следующим шагом будет написание инструмента для преобразования этих ASP-страниц в ASP.NET.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...