Software Performance Design (1) Influence of Interface Design on Software Performance Liu Yanqing Yesky
There are many problems in performance. One of the easiest modifications is that an algorithm is used when performing a computing task, for example, when the number of data is sorted, the foaming algorithm is used, and each time it is used. Data items are calculated rather than saving it, which generally we can easily discover, and once it is discovered, it can be easily corrected. However, many JAVA program performance issues are caused by some of the inter-program components of the program components that are more embarrassed, not easy to modify.
Most procedures are made by internal personnel or components "assembly" purchased from outside. Even if the software does not completely depend on the original components, the object-oriented design process also enables the application to use component forms during development, as this can simplify the design, development and debugging of the program. Although the benefits of the components are undeniable, we should also realize that the components' interface will have a significant impact on the performance and operational status of the programs used.
Maybe readers ask, what is the relationship between interface and performance? A class interface not only defines a class that can be done, but also defines its object creation behavior and the order in which it needs to be called, how the class defines whether it can be reused if this object can be reused Is it its own method creation or requires its customers to create an intermediate object, and how many methods need to be called using this class.
All these factors affect the performance of the program. One of the basic principles of performance management of Java software is: avoiding excessive objects. This does not mean that you can't create any objects that don't make full use of the various benefits of the object language language, but to develop the creation of the object when developing the performance sensitive code. The cost of object creation is quite high, we should try to avoid creating temporary or intermediate objects in performance sensitive software.
In a program that handles characters, the String class is the maximum source created by objects. Because the String class is not variable, a new object will be created whenever a String class object is modified or constructed. Therefore, a programmer with performance awareness always avoids excessive use of String class objects. However, although you try to avoid using String objects in programming, you still have found String objects often, so you can't use String class objects.
Example: Matching of expressions
As an example, you can assume that you are writing a mail server with a name for Mailbot. Mailbot needs to handle the MIME header of each message, for example, send a date or sender's mail address, which will process the MIME header by using a matching expression to make this process more simple. It places the input characters in a character buffer to process the title by indexing the buffer. Since Mailbot will call this expression matching subroutine to handle each title, this matching subscriber will be important.
Let's first look at the interface of a very low expression matching class:
Public class awfulregexpmatcher {
/ ** Create a given expression of a given expression, which will process a given string * /
Public awfulregexpmatcher (String Regexp, String InputText);
/ ** Find the next matching mode for input text, if match, return to match text, otherwise return an empty character * /
Public string getnextmatch ();
}
Even if this class uses a very efficient matching algorithm, the performance of the program that calls it will not be very good. Because the matching object is bundled with the input text, each time you call it, you need to first generate a new matching object. Since our goal is to reduce unnecessary object creation work, implement the reuse of the matching process code should be a good start. The following class defines another possible interface of the match, which allows the matchr to be reused, but performance is still not good:
Public class badregexpmatcher {
Public badregExpmatcher (String Regex);
/ ** Attempts to match the specified expression for the input text, if match, return a match, otherwise return a blank string * /
Public String Match (String INPUTTEXT);
/ ** Get the next matching character, otherwise returns a blank character * /
Public string getnextmatch ();
}
Avoiding a sensitive expression matching problem such as a returned matching sub-expression does not talk, is this definition of this class? If only from its function, it doesn't matter, but if you think of performance, it has many problems. First, the matching requires its caller to create a String class to represent the matched text. Mailbot should try to avoid generating a String object, but when it finds a title that needs to be processed, it must create a String object for BadRegexpmatcher call:
BadRegexpmatcher Datematcher = New BadRegexpmatcher;
While (...) {
...
String headerline = New String (MyBuffer, thisheaderstart,
ThisHeaderend-thisheaderstart);
String result = DATEMATCHER.MATCH (HeaderLine);
IF (result == null) {...}
}
Second, even if Mailbot only needs to get the return information that matches, no need to get the match, the matching of the match also returns a matching string. This means that in order to simply use BadRegexpMatcher to verify a specific format date title, you must also create two String objects ━━ Enter text and matching result text used by the matching. Creating two objects do not seem to have a major impact on performance, but if two objects must be created for the title of Mailbot processing, you may seriously affect the performance of the program. This problem does not appear in the design of the Mailbot itself, but is in the design of BadRegexpmatcher.
Note: Do not return a String object and return a "lightweight" Match object does not have a lot of improvements in performance. Although the cost of creating a Match object is lower than the cost of creating a String object, it still generates a char array, and copy data, still created a temporary object that is not necessary to the caller.
BadRegexpmatcher only accepts the type of input data it needs, instead of accepting the type of data we have provided, just this, it is very unsatisfactory. It will also bring other hazards using BadRegexpmatcher, where a potential hazard is to bring more effects on Mailbot's performance. Although Strings must be avoided when processing the title of the message, you must create a number of Strings objects for BadRegexpmatcher, so you may abandon the target of the String object, and more unrestricted use. A inappropriate component of a design will affect the performance of the program that uses its program, even after the expression component that does not need to use the String object, the entire program will remain affected. How to define badRegexpmatcher to avoid the above problems? First, BadRegexpmatcher should not specify its input text, which should be able to accept any of the data types that their caller can efficiently provide. Second, it should not automatically generate a String object for the matching result, just return enough information to make the caller to decide whether to generate a matching result string. (You can also provide a method to complete this task, but this is not required.) A better interface should be like this:
Class betterRegexpmatcher {
Public BetterRegexpmatcher;
/ ** Enables the match to accept the input of multiple formats, the String object, the character array, the number of characters groups, if not match, return -1; if match, return the offset address that starts matching. * /
Public int match (String InputText);
Public int match (char [] inputtext);
Public int match (char [] inputtext, int offset, int length);
/ ** If match, return the length of the match; if it is not fully matched, the calling program should be able to generate a matching string from the matching offset * /
Public int getMatchLength ();
/ ** If the calling program needs, you can easily get a subroutine of the matching string * /
Public String getMatchtext ();
}
The new interface eliminates the need for the caller to enter the text into the format required by the matching subroutine. Mailbot can call match ():
Int resultoffset = datematcher.match (MyBuffer, thisheaderstart, thisheadered-thisheaderstart);
IF (ResultoffSet <0) {...}
This has reached the design goal and has not created any new objects. In addition, its interface design also reflects the design idea of "many and simple methods" advocated by Java.
Creating an object The accurate effect of performance depends on the workload of match (). By creating and running the two express matching program classes that do not do any actual work, it will find that they have a huge difference in performance. In the Sun 1.3 JDK, the running speed ratio of the above-described code using the BetterRegexpmatcher class. 50 times faster using the BadRegexpmatcher class. By simply supporting sub-string matching, BetterRegexpmatcher can run 5 times faster than BadRegexpmatcher.