0

Session[Constant] vs Session["String Literal"] 性能

我正在检索用户特定的数据,例如ViewData["CartItems"] = Session["CartItems"];每个请求的键的字符串文字。我应该为此使用常量吗?

如果是,我应该如何实现常用的字符串文字,它会显着影响高流量网站的性能吗?


相关问题未解决 ASP.NET MVC 或Session.

4

5 回答 5

3

使用该常量,因为如果您输入错误,编译器会给您一个错误,而输入错误的字符串只会给您带来奇怪的错误。

性能差异可能非常小,很难衡量。

于 2010-04-06T19:44:14.700 回答
3

使用常量的原因与可维护性有关,而不是性能。无论哪种方式,性能都差不多。

对于字符串文字,您永远无法判断它是否与另一个字符串文字是有意或巧合相同的,因此当需要更改一个字符串时,您不知道要更改哪些其他字符串。但是如果你有常量中的值,你只需在一个地方进行更改。

坏的:

ViewData["username"] = Session["username"];

好的:

const UserNameSessionKey = "username";
const UserNameViewDataKey = "username";

ViewData[UserNameViewDataKey] = Session[UserNameSessionkey];

现在想象一下将会话键的值更改为“userName”,而不想为任何 viewdata 键更改它......

于 2010-04-06T19:58:02.650 回答
1

让我们在可维护性方面走得更远。我将引用我关于使用 Session 的其他答案:

假设我们要存储的购物车是我们的 ASP.NET MVC 应用程序的 Session。它将存储在 中Session["ShoppingCart"],但我们想要简单的强类型访问和高可测试性:

首先我们定义接口:

public interface ISessionWrapper
{
    List<CartItem> ShoppingCart { get; set; }
}

然后我们进行 HttpContext 实现:

public class HttpContextSessionWrapper : ISessionWrapper
{
    private T GetFromSession<T>(string key)
    {
        return (T) HttpContext.Current.Session[key];
    }

    private void SetInSession(string key, object value)
    {
        HttpContext.Current.Session[key] = value;
    }

    public List<CartItem> ShoppingCart
    {
        get { return GetFromSession<List<CartItem>>("ShoppingCart"); }
        set { SetInSession("ShoppingCart", value); }
    }
}

GetFromSession 和 SetInSession 是帮助在 Session 中获取和设置数据的方法。它们可以很容易地重用以访问 Session 中的其他字段。

然后我们定义我们的基本控制器(适用于 ASP.NET MVC):

public class BaseController : Controller
{
    public ISessionWrapper SessionWrapper { get; set; }

    public BaseController()
    {
        SessionWrapper = new HttpContextSessionWrapper();
    }
}

如果要在控制器外使用 Session,只需创建或注入新的 HttpContextSessionWrapper()。

您可以在 Controller 测试中将 SessionWrapper 替换为 ISessionWrapper 模拟,因此它不再依赖于 HttpContext。Session 也更容易使用,因为(List<CartItem>)Session["ShoppingCart"]你调用而不是调用SessionWrapper.ShoppingCart。它看起来更好,不是吗?

如果您不使用模型类进行视图并且我认为使用模型类更好,您可以对 ViewData 执行相同操作:

public interface IViewDataWrapper
{
    List<CartItem> ShoppingCart { get; set; }
}

public class ViewDataWrapper : IViewDataWrapper
{
}

public class BaseController : Controller
{
    public IViewDataWrapper ViewDataWrapper { get; set; }

    public BaseController()
    {
        IViewDataWrapper = new ViewDataWrapper();
    }
}

然后简单地在控制器中:

ViewDataWrapper.ShoppingCart = SessionWrapper.ShoppingCart 

或者如果您决定不使用 ViewData 和特定模型:

Model.ShoppingCart = SessionWrapper.ShoppingCart

并且只是在视图中(如果您为视图定义基类并引入此接口):

<%= ViewDataWrapper.ShoppingCart %>

或者

<%= Model.ShoppingCart %>

没有输入错误的字符串,强类型,好看。

于 2010-04-06T23:00:49.023 回答
0

只是一个简短的说明,但许多更好的示例都有一个包含字符串常量的 SessionKeys 类。这也有助于单元测试,因为您可以在必要时调用单元测试中的常量。

例如(只有一个键,但显然你可以添加更多

public class SessionKeys
{
    public const string UserDto = "UserDto";
}

就这样使用(我使用 SessionStateWrapper)

UserDto userDto = _sessionStateWrapper.GetItem(SessionKeys.UserDto) as UserDto;
于 2010-04-06T23:25:02.247 回答
0

根据这个关于字典键长度的基准,较短的键更快。在此引用:

C#中的字典字符串键长度基准

较短的查找键是否明显更快?随着键越来越短,查找时间越来越快:

  • 键 A - 20 个字符:4436 毫秒 [最慢]
  • 键 B - 10 个字符:2010 毫秒
  • 键 C - 5 个字符:1749 毫秒
  • 键 D - 2 个字符: 1575 毫秒 [最快]

在哪里:

  • 键 A = "01234567890123456789";
  • 键 B = "0123456789";
  • 键 C = "01234";
  • 键 D = "01";
于 2010-04-06T23:27:33.457 回答