字符串文字的性能与Session [...]字典键的常量

时间:2010-04-06 19:32:39

标签: c# asp.net-mvc session dictionary string-literals

Session [Constant] vs Session [“String Literal”] Performance

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

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


Related question无法解决ASP.NET MVC或Session

5 个答案:

答案 0 :(得分:3)

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

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

答案 1 :(得分:3)

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

使用字符串文字,你永远不能故意或巧合地判断它是否与另一个字符串文字相同,所以当需要更改一个时,你不知道要改变哪些字符。但是如果你有常量值,你只需在一个地方进行更改。

为:

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

好:

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

ViewData[UserNameViewDataKey] = Session[UserNameSessionkey];

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

答案 2 :(得分: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 outside controller,你只需创建或注入新的HttpContextSessionWrapper()。

您可以在Controller测试中将SessionWrapper替换为ISessionWrapper mock,因此它不再依赖于HttpContext。会话也更容易使用,因为您拨打(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 %>

没有错误输入的字符串,强类型,外观漂亮。

答案 3 :(得分:0)

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

E.g。 (只有一个键,但显然你可以添加更多

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

这样使用(我使用SessionStateWrapper)

UserDto userDto = _sessionStateWrapper.GetItem(SessionKeys.UserDto) as UserDto;

答案 4 :(得分:0)

根据this benchmark字典键的长度,较短的键更快。引用这里:

C#

中的字典字符串密钥长度基准

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

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

其中:

  • 键A =“01234567890123456789”;
  • 键B =“0123456789”;
  • 键C =“01234”;
  • 键D =“01”;