C # performance Optimization best Practices

Source: Internet
Author: User
1. Explicitly registered Evenhandler to explicitly unregister to avoid memory leaks

An event that registers a member method with an object causes the latter to hold a reference to the former. The former is not garbage collected until the event is logged off.

private void Form1_Load () {  ...  Register Event  Commandremotingcontext.cmdchanged + = new Recivercmdstatechangedeventhandler (this. commandremotingcontext_cmdchanged);  ......} private void form1_fromclosed () {  ...  Release the event  commandremotingcontext.cmdchanged-= new Recivercmdstatechangedeventhandler (this) when the form is closed. commandremotingcontext_cmdchanged);  ......}

Memory leak issues caused by an event:

    • Object A subscribes to events in object B

    • Object A has a life span far greater than object B

    • Object A does not have time to unsubscribe from Object B

    • Eventually causing object B to fail to release


2. Control-bound data source bulk operations should avoid automatic refresh

    • When clients bulk manipulate data, the control's own flush operation can cause unnecessary time consumption

    • When a data source (such as a DataTable, Array, List, ObservableCollection, or other IListSource, etc.) is bound to a control, you should break the refresh of the binding or pending controls when you bulk manipulate the data.

      This.gcBillList.DataSource = null;datarowcollection rows = this.ds.tables[0]. Rows;foreach (DataRow row in rows) {    //DataRow data operation}this.gcbilllist.datasource = This.ds.tables[0]. DefaultView;

3. Reduce the number of communication between client and server


    • WebService calls are not as small as possible, and the amount of data being transmitted can be considered split into multiple invocations

    • For short WebService calls, you should merge as much as possible to reduce the number of interactions

      Multiple calls to the same WS  txtcompanyname.text=scpubfunctionclient.publicwscal<string> ("Fortest", " Getcompanynamebyid "," 0001 ");  Txtcompanyinnername.text=scpubfunctionclient.publicwscal<string> ("Fortest", "GetCompanyInnerNameByID", " 0001 ");//merge adjacent ws  string[] result=scpubfunctionclient.publicwscal<string> (" Fortest "," Getcompanynameandinnernamebyid "," 0001 "); txtcompanyname.text=result[0];txtcompanyinnername.text= result[1];

4. Reduce the number of communication between client and server

If not necessary, try to avoid repeated calls to WebService in the loop body

The loop calls the same WS  list<person> Persons;......foreach (String PersonID in Personids) {Person=hrpubwsclient.getperson (PersonID);p ersons. ADD (person);} Merging ws  list<person> persons;......persons =hrpubwsclient.getpersonlist (personids);

5, the use of generics to avoid boxing, unpacking operations (reduce garbage collection pressure)

    • The boxing operation can cause GC pressure, and if it occurs in the collection, it should be avoided using generic collections.

    • For collections of value types, use list<t> instead of ArrayList, using Dictionary<tkey, tvalue> instead of Hashtable.

      ArrayList h=new ArrayList ();  H is not recommended. ADD (1); List<object> h = new list<object> ();  H is not recommended. ADD (1); List<int> h = new list<int> ();    Recommendation H. ADD (1);

6. String manipulation:

C # string manipulation--Reduce garbage collection pressure
7. Use constants to avoid creating objects

    • In the following example, there is a large number of new decimal (0) codes in the program, which leads to frequent creation and recycling of small objects; the correct approach is to use the Decimal.zero constant.

      private String Currencycalc () {    if (firstvalue = = new Decimal (0)) ...    if (secondvalue = = new Decimal (0))    ... if (Thirdvalue = = new Decimal (0))    ... if (Fourthvalue = = new Decimal (0))    ... ......}

8. Avoid unnecessary throwing exceptions

C # exception handling (Catch Throw) IL analysis

9. Delete multiple elements using RemoveAll rather than removeat

    • When you delete multiple elements of a collection (such as list) using the RemoveAll method, only one resize operation is performed on the internal array of the list, which is significantly more efficient than the loop call RemoveAt.

      list<string>  lst = new List<string> {"1", "2", "3", "1", "2", "4"};//Not recommended: for (int i = LST.) Count-1; I >= 0; i--) {    if (lst[i] = = "1" | | lst[i] = = "2")    {        lst. RemoveAt (i);     }} Recommendation: LST. RemoveAll (s = = s = = "1" | | s = = "2");

10. C # DataSet performance Best Practices

11. Reflection and dynamic binding--Reduce CPU consumption

    • The reflection technique converts static bindings during compilation to dynamic bindings that are deferred until run time.

    • C # mainly supports 5 kinds of dynamic creation of objects (time consumption from the network, and I measured the gap is very large, the specific test see below):

40 times times slower
How to create objects dynamically
and direct Create
1.type.invokemember
2. Contructorinfo.invoke
40 times times slower
Span style= "FONT-SIZE:14PX;" >3.activator.createinstance (Type)
slow 7 times times
4.activator.createinstance (AssemblyName, TypeName)
Span style= "FONT-SIZE:14PX;" > 1000 times times slower
5.assembly.createinstance (TypeName)
40 times times slower

    • The use of reflection and dynamic binding should be avoided as much as possible, and if necessary, follow these guidelines:

1. Transforming dynamic bindings to early binding using interface invocation (Direct call)
2. Dynamically create objects using the Activator.CreateInstance (Type) method

3. Use the typeof operator instead of the GetType call

Small bet

The time to create an instance record by looping is as follows:

Loading the assembly, getting the type at the outside time of the loop is as follows (at which time the difference in creation is quite large):


The code is as follows:

 public void Testcreateinstance () {Stopwatch watch1 = new Stopwatch ();            var asmb = Assembly.LoadFrom ("ReflectiveClassLibrary.dll"); Type type = ASMB.            GetType ("Reflectiveclasslibrary.testclass");            int num = 100000; Watch1.            Start ();                 for (int i = 0; i < num; i++) {//var ASMB = Assembly.LoadFrom ("ReflectiveClassLibrary.dll"); Type type = ASMB.                GetType ("Reflectiveclasslibrary.testclass");            Activator.CreateInstance (type); } watch1.            Stop (); Label1. Text = "Activator.CreateInstance (type Type) Time:" + watch1.            Elapsedmilliseconds + "MS"; Watch1.            Reset (); Watch1.            Start (); for (int i = 0; i < num; i++) {activator.createinstance ("reflectiveclasslibrary", "Reflectiv            Eclasslibrary.testclass "); } watch1.            Stop (); Label2. Text = "Activator.CreateInstance (string assemblyname,string TypeName) Time: "+ watch1.            Elapsedmilliseconds + "MS"; Watch1.            Reset (); Watch1.            Start ();                 for (int i = 0; i < num; i++) {//var ASMB = Assembly.LoadFrom ("ReflectiveClassLibrary.dll"); Loads the assembly ASMB.            CreateInstance ("TestClass"); } watch1.            Stop (); Label3. Text = "assembly. CreateInstance (String typeName) Time: "+ watch1.            Elapsedmilliseconds + "MS"; Watch1.            Reset (); Watch1.            Start ();                 for (int i = 0; i < num; i++) {//var ASMB = Assembly.LoadFrom ("ReflectiveClassLibrary.dll"); Type type = ASMB.                GetType ("Reflectiveclasslibrary.testclass"); Object obj = type.               InvokeMember (NULL, BindingFlags.Public | BindingFlags.Instance |            Bindingflags.createinstance, NULL, NULL, NULL); } watch1.            Stop (); Label4. Text = "Type.invokeMember (string name, BindingFlags invokeattr, Binder binder, Object target, object[] args) Time: "+ watch1.            Elapsedmilliseconds + "MS"; Watch1.            Reset (); Watch1.            Start ();                 for (int i = 0; i < num; i++) {//var ASMB = Assembly.LoadFrom ("ReflectiveClassLibrary.dll"); Type type = ASMB.                GetType ("Reflectiveclasslibrary.testclass"); ConstructorInfo ConstructorInfo = type.                GetConstructors () [0];            Constructorinfo.invoke (NULL); } watch1.            Stop (); Label5. Text = "Contructorinfo.invoke (object[] parameters) Time:" + watch1.        Elapsedmilliseconds + "MS"; }


Loading the assembly, getting the type in the loop internal time is as follows (at this point the difference in the creation of time-consuming gap is relatively small):


The code is as follows:

 public void Testcreateinstance () {Stopwatch watch1 = new Stopwatch ();            var asmb = Assembly.LoadFrom ("ReflectiveClassLibrary.dll"); Type type = ASMB.            GetType ("Reflectiveclasslibrary.testclass");            int num = 100000; Watch1.            Start ();                for (int i = 0; i < num; i++) {var asmb = Assembly.LoadFrom ("ReflectiveClassLibrary.dll"); Type type = ASMB.                GetType ("Reflectiveclasslibrary.testclass");            Activator.CreateInstance (type); } watch1.            Stop (); Label1. Text = "Activator.CreateInstance (type Type) Time:" + watch1.            Elapsedmilliseconds + "MS"; Watch1.            Reset (); Watch1.            Start (); for (int i = 0; i < num; i++) {activator.createinstance ("reflectiveclasslibrary", "Reflectiv            Eclasslibrary.testclass "); } watch1.            Stop (); Label2. Text = "Activator.CreateInstance (string assemblyname,string TypeName) Time: "+ watch1.            Elapsedmilliseconds + "MS"; Watch1.            Reset (); Watch1.            Start ();                for (int i = 0; i < num; i++) {var asmb = Assembly.LoadFrom ("ReflectiveClassLibrary.dll"); Loads the assembly ASMB.            CreateInstance ("TestClass"); } watch1.            Stop (); Label3. Text = "assembly. CreateInstance (String typeName) Time: "+ watch1.            Elapsedmilliseconds + "MS"; Watch1.            Reset (); Watch1.            Start ();                for (int i = 0; i < num; i++) {var asmb = Assembly.LoadFrom ("ReflectiveClassLibrary.dll"); Type type = ASMB.                GetType ("Reflectiveclasslibrary.testclass"); Object obj = type.               InvokeMember (NULL, BindingFlags.Public | BindingFlags.Instance |            Bindingflags.createinstance, NULL, NULL, NULL); } watch1.            Stop (); Label4. Text = "Type.InvokeMember(String name, BindingFlags invokeattr, Binder binder, Object target, object[] args) Time: "+ watch1.            Elapsedmilliseconds + "MS"; Watch1.            Reset (); Watch1.            Start ();                for (int i = 0; i < num; i++) {var asmb = Assembly.LoadFrom ("ReflectiveClassLibrary.dll"); Type type = ASMB.                GetType ("Reflectiveclasslibrary.testclass"); ConstructorInfo ConstructorInfo = type.                GetConstructors () [0];            Constructorinfo.invoke (NULL); } watch1.            Stop (); Label5. Text = "Contructorinfo.invoke (object[] parameters) Time:" + watch1.        Elapsedmilliseconds + "MS"; }


The test code is as follows:

C # Reflection Test Demo

12. Serialization and deserialization

    • Protobuf is more efficient than XML, binary serialization, and supports a large number of data

    • The size of the PROTOBUF serialization is 1/20 of the JSON 1/10,xml format, which is a binary serialized 1/10

The above is the content of C # performance optimization best practices, please pay attention to topic.alibabacloud.com (www.php.cn) for more information!

  • Related Article

    Contact Us

    The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

    If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

    A Free Trial That Lets You Build Big!

    Start building with 50+ products and up to 12 months usage for Elastic Compute Service

    • Sales Support

      1 on 1 presale consultation

    • After-Sales Support

      24/7 Technical Support 6 Free Tickets per Quarter Faster Response

    • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.