简体   繁体   中英

Does Having Hundreds of Readonly Static Variables Cause Performance Issues?

I am working on a new Asp.Net MVC project and this time to have better control over the static contents of the application, I am planning to store all content as reusable properties in readonly static variables . These values are not going to change throughout the application's lifecycle.

Example of usage:

  • I have created a class holding all messages in static variables so that if I want to change let's say, the default save message I can change it from here without having a need to change every occurrence in the project. This includes validation messages also. (numbers could grow rapidly, depending upon the size of the project)

  • Other usages: To store all application-related properties such as version, title, keys, and many more. I am also planning to store the button texts and other UI controls-related properties so that they can be easily customized, such as I don't know maybe CSS classes.

  • And not to mention, apart from the above I also have a number of static classes such as Data Access Helpers and Utility Functions with some static methods.

Sample Class:

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.";
        }
    }

As of now, these are all on paper only. I am willing to take this approach so that I can easily customize the text contents according to different clients' needs. But before that, I have a few doubts to clear.

  • Does all static variables initialized and stored in memory as we run the web application?
  • Does all static variables remain in memory throughout the lifecycle of the web application, irrespective of its usage in the current View?
  • Does the compiler replace the occurrences of the static variable with its actual value at the time of converting the source code into bytecode? (I have seen this in java when I decompiled the class file, wherever I used the static variables, it is replaced with its actual value).

Another Example:

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;
        }
    }

Usage in View

@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>
}

Does Having Hundreds of Readonly Static Variables Cause Performance Issues?

No. The variables in your example are a few bytes each. Let's say you have 500 variables, and they are 20 bytes each. That would be 10KB. Modern web servers generally have several gigabytes of memory, so it is unlikely that you face any performance issue because you are caching 10KB of data. See here for more info about static variables .


IMO, the main issue with having too many static types (class/variable) is that you don't know where to find them. In the examples that you have provided, it seems like you are hardcoding some constants into static variables. IMO that's fine, provided:

  1. You don't define configuration variables as constants (things like connection strings, which are environment dependent)
  2. You are using a logical approach to group these constants, so they are easy to find
  3. I would try to limit the size of such constants (not because of performance but to keep the code clean)

Looking at your code, there might be more elegant ways to achieve this, for example you can define an interface called IResponse :

interface IResponce
{
   short Code { get; }

   string CssColor { get; }

   string GetMessage();
}

and define different classes for response types, for example:

public class SuccessResponse : IResponse
{
   public short Code => 0;

   string CssColor => "green";

   public string GetMessage()
   {
      return "Process completed successfully";
   }
}

public class FailureResponse : IResponse
{
   public short Code => 1;

   string CssColor => "red";

   public string GetMessage()
   {
      return "Process failed";
   }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM