拥有数百个只读静态变量是否会导致性能问题?

mad*_*285 5 asp.net asp.net-mvc web-applications static-variables readonly-variable

我正在开发一个新的应用程序,Asp.Net MVC project这次是为了更好地控制应用程序的静态内容,我计划将所有内容作为可重用属性存储在readonly static variables. 这些值在应用程序的整个生命周期中不会改变。

使用示例:

  • 我创建了一个类,将所有消息保存在静态变量中,这样如果我想更改默认保存消息,我可以从这里更改它,而无需更改项目中的每个事件。这还包括验证消息。(数量可能会快速增长,具体取决于项目的规模)

  • 其他用途:存储所有与应用程序相关的属性,例如版本、标题、密钥等等。我还计划存储按钮文本和其他 UI 控件相关的属性,以便可以轻松自定义它们,例如我不知道可能是 CSS 类。

  • 更不用说,除了上述之外,我还有许多静态类,例如数据访问助手和带有一些静态方法的实用函数。

示例类:

public static class Messages
    {
        public static class Response
        {
            public readonly static string SUCCESS = "Process completed successfully";
            public readonly static string FAILED = "Process failed";
            public readonly static string ERROR = "Some error occured";
            public readonly static string OPRNOTPERFORMED = "Operation aborted/failed for some unknown reason. Please contact your administrator";

            //LOGIN
            public readonly static string USERNOTFOUND = "Invalid username or password";
            public readonly static string USERINACTIVE = "User is not active. Please contact your administrator";
            public readonly static string NOROLEDEFINED = "User does not have any valid authority to access the application. Please contact your administrator";
            public readonly static string FORCELOGOUT = "You have been logged out. Please login again";

            //MASTERS
            public readonly static string NOSTATESFOUND = "No states found in database. please contact your administrator";
            public readonly static string APPCHOICENOTFOUND = "Option not found in the database. Please contact your system administrator.";

            //COMPANY
            public readonly static string INVALIDCOMPANY = "Please sign out from the application and login again before performing further opreations";
        }
        public static class Description
        {
            //COMPANY
            public readonly static string INVALIDCOMPANY = "Company value changed between 2 consiquent requests. This happens when you left the page idle for so long. Please login again before performing further operations.";
        }
        public static class Instructions
        {
            public readonly static string MANDATORY_FIELDS = "Fields marked with <i class='text-warning-dark fw-bold fs-6'>*</i> cannot be blank.";
        }
    }
Run Code Online (Sandbox Code Playgroud)

截至目前,这些都还只是纸上谈兵。我愿意采用这种方法,这样我就可以根据不同客户的需求轻松定制文本内容。但在此之前,我有几个疑问需要澄清。

  • 当我们运行 Web 应用程序时,所有静态变量是否都已初始化并存储在内存中?
  • 所有静态变量是否在 Web 应用程序的整个生命周期中都保留在内存中,无论其在当前视图中的使用情况如何?
  • 在将源代码转换为字节码时,编译器是否将静态变量的出现替换为其实际值?(当我反编译类文件时,我在java中看到了这一点,无论我在哪里使用静态变量,它都会被替换为其实际值)。

另一个例子:

public class Select
    {
        private static readonly SelectListItem defaultChoice = new SelectListItem { Text = "Select", Value = "" };
        public static readonly IEnumerable<SelectListItem> ISACTIVE = new List<SelectListItem>
        {
            new SelectListItem {Text = "Active", Value = "true"},
            new SelectListItem {Text = "Inactive", Value = "false"}
        };
        private static IList<SelectListItem> STATES;

        public static IEnumerable<SelectListItem> GetStates(string sessionHash)
        {
            if (sessionHash == null)
            {
                return null;
            }
            if (STATES == null)
            {
                StateService stateService = new StateService(sessionHash);
                ProcessResponse response = stateService.GetStates();
                IList<StateModel> statesModel = (IList<StateModel>)response.Data[0];
                STATES = new List<SelectListItem>();
                STATES.Add(defaultChoice);
                foreach (StateModel state in statesModel)
                {
                    STATES.Add(new SelectListItem { Text = state.Name, Value = state.StateId.ToString() });
                }
            }
            return STATES;
        }

        public static IEnumerable<SelectListItem> AppChoices(IList<AppChoicesModel> choicesModel)
        {
            IList<SelectListItem> choices = new List<SelectListItem>();
            choices.Add(defaultChoice);
            if (choicesModel != null && choicesModel.Count > 0)
            {
                foreach(AppChoicesModel choice in choicesModel)
                {
                    choices.Add(new SelectListItem { Text = choice.Text, Value = choice.Value });
                }
            }
            return choices;
        }
    }
Run Code Online (Sandbox Code Playgroud)

视图中的用法

@model Cygnus.View.Models.Company.CompanyBranch
@using Cygnus.Data.Constants

@{
    Layout = "~/Views/Shared/_LayoutDashboard.cshtml";
    ViewBag.Title = Titles.Company.BRANCHT;
    ViewBag.SubTitle = Titles.Company.BRANCHST;
    var moduleName = Routes.Company.BRANCH;
    var isActive = Select.ISACTIVE;
    var states = Select.GetStates(Session[Codes.SessionParams.HASH].ToString());
    Html.RenderPartial(Routes.Commons.PROCRESPONSE);
}

<div class="container-fluid">
    <div class="row">
        <!-- left column -->
        <div id="@string.Format("{0}Form_Container", @moduleName)" class="col-md-7 mt-1 collapse show">
            <!-- general form elements -->
            <div class="card card-info">
                <div class="card-header">
                    <h3 class="card-title">@ViewBag.SubTitle</h3>
                </div>
                <!-- /.card-header -->
                <!-- form start -->
                @using (Html.BeginForm(moduleName, Routes.Company.CONTROLLER, FormMethod.Post, new { @name = moduleName }))
                {
                    @Html.HiddenFor(model => model.CompanyId)
                    @Html.HiddenFor(model => model.CompanyBranchId)
                    @Html.AntiForgeryToken()
                <div class="card-body">
                    <div class="row gx-3">
                        <div class="col-10">
                            <i class="fas fa-info-circle text-info mr-2"></i>@Html.Raw(@Messages.Instructions.MANDATORY_FIELDS)
                        </div>
                        <div class="col-2">
                            <button class="btn btn-block btn-info btn-flat size-width-auto float-right" value="@Codes.ButtonValue.ADD" name="@Codes.ButtonGroupName.ACTION" ><i class="fas fa-plus-square fa-1xl align-middle mr-2"></i><span class="align-middle">@Codes.ButtonValue.NEW</span></button>
                        </div>
                    </div>
                    <div class="row gx-3 mt-3">
                        <div class="input-group-sm col">
                            <label for="Name" class="fw-semibold">@Html.DisplayNameFor(model => model.Name)</label>
                            @Html.EditorFor(model => model.Name, new { htmlAttributes = new { @class = "form-control input-required", @placeholder = "Branch Name" } })
                            @Html.ValidationMessageFor(model => model.Name, "", new { @class = "text-danger fs-6-5" })
                        </div>
                        <div class="input-group-sm col-4">
                            <label for="Code" class="fw-semibold">@Html.DisplayNameFor(model => model.Code)</label>
                            @Html.EditorFor(model => model.Code, new { htmlAttributes = new { @class = "form-control input-required", @placeholder = "Branch Code" } })
                            @Html.ValidationMessageFor(model => model.Code, "", new { @class = "text-danger fs-6-5" })
                        </div>
                    </div>
                    <div class="row gx-3 mt-5px">
                    <div class="input-group-sm col">
                        <label for="State" class="fw-semibold">@Html.DisplayNameFor(model => model.State)</label>
                        @Html.DropDownListFor(model => model.State, states, new { @class = "form-control input-required" })
                        @Html.ValidationMessageFor(model => model.State, "", new { @class = "text-danger fs-6-5" })
                    </div>
                    <div class="input-group-sm col-2">
                        <label for="Pincode" class="fw-semibold">@Html.DisplayNameFor(model => model.Pincode)</label>
                        @Html.EditorFor(model => model.Pincode, new { htmlAttributes = new { @class = "form-control input-required", @placeholder = "Pincode" } })
                        @Html.ValidationMessageFor(model => model.Pincode, "", new { @class = "text-danger fs-6-5" })
                    </div>
                    <div class="input-group-sm col">
                        <label for="BranchType" class="fw-semibold">@Html.DisplayNameFor(model => model.BranchType)</label>
                        @Html.DropDownListFor(model => model.BranchType, Model.BranchTypeList, new { @class = "form-control input-required" })
                        @Html.ValidationMessageFor(model => model.BranchType, "", new { @class = "text-danger fs-6-5" })
                    </div>
                </div>
                    <div class="row gx-3 mt-5px">
                        <div class="input-group-sm col">
                            <label for="IsActive" class="fw-semibold">@Html.DisplayNameFor(model => model.IsActive)</label>
                            @Html.DropDownListFor(model => model.IsActive, isActive, new { @class = "form-control" })
                            @Html.ValidationMessageFor(model => model.IsActive, "", new { @class = "text-danger fs-6-5" })
                        </div>
                    </div>
                </div>
                    <!-- /.card-body -->
                    <div class="card-footer">
                        <button type="submit" value="@Codes.ButtonValue.SAVE" name="@Codes.ButtonGroupName.ACTION" class="btn btn-success px-5">@Codes.ButtonValue.SAVE</button>
                        <div>@Html.ValidationSummary(true, "", new { @class = "text-danger" })</div>
                    </div>
                }
            </div>
            <!-- /.card -->
        </div>
        <div class="col-md mt-1">
            @{
                Html.RenderAction(Routes.Company.BRANCHLIST, Routes.Company.CONTROLLER);
            }
        </div>
    </div>
</div>
@section Scripts {
    @Scripts.Render("~/Scripts/Cygnus/Company.js")
    <script>
        $(function () {
            var tableId = "#listOfCompanyBranch";
            initDataTableWithDefaultToolbar(tableId, '@moduleName');
            attachRowDataEvenOnATag(tableId);
        });
        function onRowClicked(rowData, row) {
            let formElement = $("#@string.Format("{0}Form_Container",moduleName)");
            if ($(formElement).is('.collapse:not(.show)'))
                $(formElement).collapse("show");
            document.getElementById("CompanyBranchId").value = $(row).attr("data-branch");
            document.getElementById("CompanyId").value = $(row).attr("data-company");
            FillFormControls(formArr["@moduleName"], rowData);
            $("#IsActive").val((rowData[13]).toLocaleLowerCase());
        }
    </script>
}
Run Code Online (Sandbox Code Playgroud)

Hoo*_*ini 3

\n

拥有数百个只读静态变量是否会导致性能\n问题?

\n
\n

不。您示例中的变量每个都是几个字节。假设您有 500 个变量,每个变量有 20 个字节。那将是 10KB。现代 Web 服务器通常具有几 GB 的内存,因此您不太可能遇到任何性能问题,因为您正在缓存 10KB 的数据。有关静态变量的更多信息,请参见此处。

\n
\n

IMO,拥有太多静态类型(类/变量)的主要问题是您不知道在哪里找到它们。在您提供的示例中,您似乎将一些常量硬编码为静态变量。IMO 认为\xe2\x80\x99s 很好,前提是:

\n
    \n
  1. 您不\xe2\x80\x99t 将配置变量定义为常量(例如连接字符串,取决于环境)
  2. \n
  3. 您正在使用逻辑方法对这些常量进行分组,因此很容易找到它们
  4. \n
\n

我会尝试限制此类常量的大小(不是因为性能而是为了保持代码干净)

\n
\n

查看您的代码,可能有更优雅的方法来定义其中一些常量,例如您可以定义一个名为的接口IResponse

\n
interface IResponce\n{\n   short Code { get; }\n\n   string CssColor { get; }\n\n   string Message { get; }\n}\n
Run Code Online (Sandbox Code Playgroud)\n

并为响应类型定义不同的类,例如:

\n
public class SuccessResponse : IResponse\n{\n   public short Code => 0;\n\n   public string CssColor => "green";\n\n   public string Message => "Process completed successfully";\n}\n\npublic class FailureResponse : IResponse\n{\n   public short Code => 1;\n\n   string CssColor => "red";\n\n   public string Message => "Process failed";\n}\n
Run Code Online (Sandbox Code Playgroud)\n

  • 感谢您的建议以及您分享的有关静态变量的链接。谢啦!! (2认同)