我可以在ASP中延迟执行吗?或者:请提供有关提高旧ASP站点性能的任何帮助

时间:2009-05-26 12:55:19

标签: performance asp-classic

我正在努力提高用经典ASP编写的网站的性能。

它支持多种语言,问题在于如何实现。它有以下方法:

GetTranslation(id,language)

这样的商店叫做:

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

该方法只是在SQL中查找ID和语言并返回翻译。简单。

但效率低得令人难以置信。在每个页面加载时,大约有300个独立的SQL调用来获得单独的翻译。

我已经在许多场景中显着提升了性能:

  • 一个C#工具,用于扫描.asp文件并获取对GetTranslation的引用
  • 然后,该工具构建一个“批量缓存”方法,该方法(取决于页面)获取它找到的所有ID,并一次性将结果缓存到字典中。
  • 然后更新了GetTranslation方法以检查字典中是否有任何请求,只有当它不在那里时才转到SQL(并在必要时缓存它自己的结果)

这只是到目前为止。

当翻译的ID存储在数据库中时,我无法选择这些(特别容易)。

理想情况下 GetTranslation方法会在每次调用时构建一个只在页面请求结束时执行的大型SQL字符串。

在ASP中这可能吗?我可以得到&lt;%= ...%&gt;的结果吗?成为参考后来解决了什么?

我也真诚地感谢任何其他创造性的方法,我可以改善这个古老丑陋的野兽的表现。

5 个答案:

答案 0 :(得分:2)

我认为你不能在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

这肯定会减少对DB的调用。但您需要非常小心关于您将多少数据放入应用程序对象。你不想失去记忆。您最好还跟踪翻译在内存中保留多长时间并在一段时间内未访问时将其从Application对象中删除。

答案 1 :(得分:0)

<%= x %>只是转换为Response.Write(x)。没有办法推迟。

事实上,据我所知,Classic ASP无法将任何推迟。

在编写缓存工具方面,您已经做了很多工作。下一步是编写一个工具将这些ASP页面转换为ASP.NET。

答案 2 :(得分:0)

你的缓存是你可以在这里做的最好的保存,你可以消除.net pre-cacher的复杂性,只需每次调用​​GetTranslate检查你的字典的条目,如果没有那么它可以获取它并将其缓存在应用程序空间中。这将是快速的减轻。然后就是偶尔刷新Cache的问题,但是当工作进程刷新时,每隔24小时就会完成一次。

如果您需要它更新,那么您可以像使用.net cacher一样提取所有参考文献。然后你可以创建一个新的函数来获取给定的一组id的所有条目,在每个页面的ASP页面顶部附近写一个对该函数的调用,这将调用你的数据库,一个SQL字符串将结果存入一个当地字典。然后修改GetTranslation以使用此字典中的值。需要更新,但这可能是您的构建过程的一部分,或者只是每小时/每晚运行的作业。

答案 3 :(得分:0)

我们在电子商务系统中使用具有命名空间和语言属性的i18n类。该类有一个名为'translate'的默认函数,它基本上预先形成字典查找。使用包含命名空间和语言的所有翻译的文本文件中的memento模式加载此字典。

这些翻译文件的骨架是由自定义工具(实际用vbscript编写)生成的,它解析ASP的i18n($ somestring)调用。文件名基于命名空间和语言,例如“shoppingcart_step_1_FR.txt”。当我们向ASP代码添加新的可翻译字符串时,该工具实际上可以更新/扩展现有的翻译文件,这对维护非常重要。

使用此方法的性能开销很小。由于分割,我们最大的翻译文件包含大约200个可翻译字符串(包括静态图像网址)。根据请求加载它对性能的影响很小。我想可以使用一些第三方的tessafe字典来缓存应用程序对象中的翻译词典,但恕我直言,这不值得麻烦。

额外提示,在字符串中使用变量替换以提高可翻译性。 例如使用:

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

而不是

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

第一种方法对翻译人员来说更灵活。很多语言都有不同的句子结构。

答案 4 :(得分:0)

我在自己的CMS中使用的方法是在启动时使用基于变量名,语言ID和CMS实例的唯一键将所有静态语言字符串从数据库加载到Application对象中。然后,当页面被创建时,我将页面级缓存用于数组,因此重复使用变量得到缓存,并避免在可能的情况下大量访问Application对象。我使用数组而不是字典作为我的CMS功能每个页面创建的方式,每个部分彼此隔离,所以我将每页创建多个字典,这是不可取的。

显然,此解决方案的可行性完全取决于您拥有的变量数量以及您拥有的翻译数量以及每页需要检索的变量数量。