Производительность строковых литералов в сравнении с константами для ключей [...] словаря сеанса - PullRequest
0 голосов
/ 06 апреля 2010

Session [Constant] vs Session ["String Literal"] Производительность

Я получаю пользовательские данные, такие как ViewData["CartItems"] = Session["CartItems"]; со строковым литералом для ключей при каждом запросе.Должен ли я использовать константы для этого?

Если да, то как мне следует реализовать часто используемые строковые литералы и значительно ли это повлияет на производительность на сайте с большим трафиком?


Смежный вопрос не относится к ASP.NET MVC или Session.

Ответы [ 5 ]

3 голосов
/ 06 апреля 2010

Причина использования констант связана с ремонтопригодностью, а не с производительностью. Производительность примерно одинакова в любом случае.

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

Bad:

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

Хорошо:

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

ViewData[UserNameViewDataKey] = Session[UserNameSessionkey];

Теперь представьте, что вы изменили значение ключа сеанса на «userName», не желая менять его для какого-либо ключа viewdata ...

3 голосов
/ 06 апреля 2010

Используйте константу, потому что компилятор выдаст вам ошибку, если вы введете ее неправильно, а строки с ошибками - только ошибочные ошибки.

Разница в производительности, вероятно, будет настолько мала, что ее будет очень трудно измерить.

1 голос
/ 07 апреля 2010

Пойдем дальше с ремонтопригодностью. Я процитирую мой другой ответ об использовании сеанса:

Допустим, мы хотим сохранить корзину покупок - это сессия нашего приложения ASP.NET MVC. Он будет храниться в 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. Их можно легко использовать для доступа к другим полям в сеансе.

Затем мы определяем наш базовый контроллер (применимый к ASP.NET MVC):

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

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

Если вы хотите использовать Session вне контроллера, вы просто создаете или внедряете новый HttpContextSessionWrapper ().

Вы можете заменить SessionWrapper на макет ISessionWrapper в тестах контроллера, чтобы он больше не зависел от 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 %>

Никаких опечаток, строго типизированных, симпатичных.

0 голосов
/ 07 апреля 2010

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

Тест длины ключа словарной строки в C #

Значительно ли короткие ключи поиска значительно быстрее? Когда ключи становятся короче, время поиска становится быстрее:

  • Ключ A - 20 символов: 4436 мс [медленнее]
  • Ключ B - 10 символов: 2010 мс
  • Ключ C - 5 символов: 1749 мс
  • Ключ D - 2 символа: 1575 мс [быстрый]

где:

  • Ключ A = "01234567890123456789";
  • Ключ B = "0123456789";
  • Ключ C = "01234";
  • Ключ D = "01";
0 голосов
/ 07 апреля 2010

Просто краткое замечание, но во многих лучших примерах есть класс SessionKeys, содержащий строковые константы. Это также помогает модульному тестированию, поскольку при необходимости вы можете вызывать константы в своих модульных тестах.

например. (только один ключ, но, очевидно, вы можете добавить больше

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

используется как таковой (я использую SessionStateWrapper)

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