It turned out to be the ghost of the movie albyrefobject ......

Source: Internet
Author: User

A forced conversion is fast or tostring is fast, which makes me dizzy. I thought it was okay, but there was a strange situation. Fortunately, there was no doubt that there was no way.

At the beginning, I think everyone thinks that tostring is slow and dangerous, as I guess. At the beginning, my test results were consistent with my guess. tostring was a little slower than forced conversion. Different machines have different results, ranging from. However, some people later said that the differences under the console made me confused. In fact, this has nothing to do with GDI, form, and doevents functions, because I have not used irrelevant things or measured unnecessary parts. What makes me more interesting is that, even under the console, the test results will be slow as long as the classes written by myself inherit from the form. If the inheritance relationship is canceled, the speed of the two will be almost the same. It is considered that form initialization will be complicated, native resources will be used, and the efficiency problem will be solved when objects are released. These are all wrong, because I obviously did not continuously construct and release them, this part of time is not included. So what is the problem? There was no time for the test yesterday. We got up early in the morning to perform the test.
In fact, I noticed the call after the tostring under the assembly at the beginning. I always felt very strange: Why don't I need to call the value assignment after the forced conversion? (Below)
00000112 mov ESI, eax
00000114 push ESI
00000115 mov ECx, EDI
00000117 mov edX, 995358 H
0000011c call 71e7030d

So I suspected from the very beginning that performance loss was at this point, but because there is no way to tune it internally (MS debugger ......), So I can only make some guesses: is it related to the instance where the test is located?
Use one sentenceCodeFor example:
S = O. tostring ();
Originally, the performance should only depend on the method called (tostring or forced conversion) and the type of the called object (related to O ). For example, if tostring is a virtual function, it may be related. But after seeing this series of strange results, I had to suspect that this test was related to this.

First I guess, is it related to the depth of inheritance? If this is the case, it would be ridiculous, but one of the differences between the Form class and the Self-written class is the inheritance depth, which is still a reason for suspicion. To verify this problem, two classes are written:

Public   Class Testbase
{
Protected Const IntTestround= 100000000;
Private StringStestbase;
Public VoidTest ();
} Public   Class First: testbase
{
Private StringSfirst;
Public VoidFirsttest ();
}

Construct the corresponding instance and do not call test and firsttest. The code inside the function is roughly as follows:

Object O =   " Hello! This is a test! " ;
Long DT;
Int I;

DT = Datetime. Now. ticks;
For (I =   0 ; I < Testround; I ++ )
{
Sfirst=(String) O;
}
DT = Datetime. Now. ticks - DT;
Console. writeline (Dt. tostring ( " N " ));

DT = Datetime. Now. ticks;
For (I =   0 ; I < Testround; I ++ )
{
Sfirst=O. tostring ();
}
DT = Datetime. Now. ticks - DT;
Console. writeline (Dt. tostring ( " N " ));

Writing two functions here is mainly to avoid the potential impact of virtual functions. Although it is not possible, it is better not to develop out-of-band functions. The test results show that there is almost no difference. I still don't have to worry about it. I extended the inheritance depth from Layer 1 to Layer 3, and the test results are the same. Therefore, the impact of inheritance depth is excluded.
Then I had to doubt whether some interfaces are implemented inside the object, which may lead to performance differences. Because the form does implement many interfaces internally, though this is ridiculous. So I wrote another class:

Public   Class Second: first, icloneable, icomparable, iformattable, iserviceprovider, idisposable, iconvertible, partial, primary, secondary, idbcommand, primary, secondary, icontainercontrol, idataadapter, ibuttoncontrol, primary, secondary, secondary, imessagefilter, itablemapping, iwin32window, iwindowtarget, itablemappingcollection
{
Private StringSSecond;
Public VoidSecondtest ();
//Interface implementation is not pasted
}

Don't blame me for it. I added three interfaces at the beginning, and observed the difference of several dozen milliseconds, so I added them all the way. At last, we found that the difference would not exceed 100 milliseconds, and it is likely to be caused by errors. Now there are no problems with more than 20 interfaces added. What exactly is the problem?
Let's look at the rest of the form's parent class. Isn't it really something about the loss of performance in the constructor? It's so depressing and ridiculous. No way. I guess it won't solve the problem. Let's test it. Let's see how the test method works? If you want to find out the problem from the top parent class, that is to say, design a class derived from marshalbyrefobject:

Public   Class Fourth: financialbyrefobject
{
Private StringSfourth;
Public VoidFourthtest ();
}

Unexpectedly, I don't know. The next hop in a test is caused by marshalbyrefobject. The test results are very consistent with the above. Later, I did more tests to mine more data. For example, if the test function is on an instance, but sfourth is static, what would happen? What if the function is static but the global variable is on the instance? Are both static? Therefore, more functions are written for testing:

Public   Void Teststatic ();
Static   Public   Void Statictest (fourth );
Static   Public   Void Staticteststatic (fourth );

I tested this test under. NET 1.1 (Debug) and. NET 2.0 (debug/release) respectively. The test results are as follows:

Description . NET 1.1 debug . NET 2.0 debug . NET 2.0 release
testbase: Object
string = (string) O
string = O. tostring ()

first: testbase
string = (string) O
string = O. tostring ()

Second: first, interfaces
string = (string) O
string = O. tostring ()

third: First
string = (string) O
string = O. tostring ()

Fourth: marshalbyref
string = (string) O
string = O. tostring ()
string = myclass. getstring ()
string = This. getstring ()
string = fourth. getstring ()

fourth
static string sstatic;
Public void teststatic ()
{< br> sstatic = This. something
}

fourth
private string sfourth;
static public void statictest (OBJ)
{< br> sfourth = obj. something
}

fourth
static string sstatic;
static public void staticteststatic ()
{< br> sstatic = fourth. something
}

--- end of test ---

testbase
10,625,000.00
11,250,000.00

first
10,468,750.00
11,093,750.00

second
10,781,250.00
10,937,500.00

third
10,468,750.00
11,093,750.00

fourth
10,625,000.00
109,062,500.00
110,937,500.00
120,781,250.00
109,062,500.00

fourth
10,468,750.00
11,093,750.00
11,093,750.00
24,843,750.00
10,156,250.00

fourth
106,718,750.00
108,125,000.00
109,687,500.00
119,218,750.00
106,875,000.00

fourth
10,312,500.00
11,093,750.00
11,093,750.00
24,843,750.00
10,156,250.00

done

testbase
10,781,250.00
15,312,500.00

first
10,312,500.00
15,781,250.00

second
11,250,000.00
15,468,750.00

third
10,312,500.00
14,531,250.00

fourth
9,687,500.00
125,625,000.00
120,312,500.00
131,093,750.00
118,281,250.00

fourth
8,593,750.00
12,656,250.00
12,968,750.00
27,343,750.00
12,187,500.00

fourth
117,343,750.00
118,906,250.00
119,687,500.00
131,406,250.00
121,562,500.00

fourth
8,593,750.00
12,656,250.00
12,968,750.00
28,125,000.00
12,031,250.00

done

Testbase
8,125,000.00
12,968,750.00

First
7,656,250.00
12,968,750.00

Second
8,281,250.00
15,468,750.00

Third
7,187,500.00
13,437,500.00

Fourth
7,812,500.00
12,812,500.00
5,156,250.00
25,625,000.00
6,093,750.00

Fourth
12,812,500.00
15,156,250.00
6,093,750.00
24,687,500.00
6,250,000.00

Fourth
113,750,000.00
115,156,250.00
109,062,500.00
126,718,750.00
109,062,500.00

Fourth
6,875,000.00
12,031,250.00
5,156,250.00
22,968,750.00
5,156,250.00

Done

(Let's Talk About the. NET 2.0 release data, which is a strange data .)

I never imagined at first that a simple value assignment statement like A = B will also be related to the position declared by the variable A (in the case of global variables ), or it is related to the class where A is located. I thought it wasn't just to assign B to A. in the compilation, mov or Lea is done. How to obtain B is the key to affecting performance. The results show that. NET is not so simple, at least there will be the special case of marshalbyrefobject. I have also heard that marshalbyrefobject will affect performance very much,ArticleI did not mention it, and I have never studied it myself. In my mind, what is the relationship between this financialbyrefobject and me? Now it seems that there is a little relationship between them. For example, you have a global variable on the form (including all the controls on the window are local variables ), if you assign a value to him, performance loss will occur. Fortunately, we often do not constantly copy a global variable. For example, we cannot always assign a value to the global variable "button mybutton" for 100000000 times? At most, we may keep adding content to the global variable hashtable HT. Fortunately, the Collection types such as hashtable are not inherited from marshalbyrefobject. If that is the case, it will be crazy ......

This discovery may be useful and useless, at least in vs2k5. However. net CF is hard to say, although I intuitively think it is impossible to make too many optimizations, and there is no content in marshalbyrefobject, I don't know. will net CF be specially treated?

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.