When writing a program, developers usually translate the operation logic that has been designed or conceived directly in programming languages. About the Author
Wang Dandan, a software engineer at IBM China system and technology center, has been engaged in Web system design and development since joining IBM in 2006. He has five years of PHP application design and development experience.
When writing a program, developers usually translate the operation logic that has been designed or conceived directly in programming languages. It is a pleasure that the program can be compiled smoothly. If the running time of the program is acceptable at this time, the program will be immersed in the sense of accomplishment of writing code, and the code optimization is often ignored in this process. Optimization is taken into consideration only when the program running speed is affected. This article mainly introduces how to use arrays to reduce the time complexity caused by multi-layer loops in PHP programming. Especially when the program needs to interact with the database multiple times, using this method to optimize your code will bring unexpected results.
What is the time complexity of an algorithm?
Time complexity is the main factor that developers use to measure the merits and demerits of application algorithms. Objectively speaking, the advantages and disadvantages of algorithms are not only related to time complexity, but also closely related to space complexity. As the hardware configuration of devices continues to improve, the space complexity of algorithms is also relaxed for small and medium-sized applications. However, in today's Web era, the time complexity of applications has higher requirements.
What is the time complexity of the algorithm? In summary, it refers to selecting an original operation that can represent the algorithm from the algorithm, and measuring the number of times the original operation is repeated as the algorithm's time. There are two factors that affect the time complexity: one is the execution time of the original operation, and the other is the number of executions of the original operation due to the control structure. It is easier to reduce the time complexity of the algorithm and reduce the number of original operations. The method described in this article is to use PHP arrays to reduce the execution times of the original operation and reduce the time complexity of the algorithm.
The algorithm's time measurement is recorded as T (n) = O (f (n )), it indicates that the number of repeated executions of the basic operation in the algorithm is a function f (n) of the problem scale n. that is to say, as the problem scale n increases, the algorithm execution time increases and f (n) the growth rate is the same. In most cases, we take the statements in the deepest loop as the original operation to discuss the time complexity of the algorithm, because the execution frequency is the same as the frequency of the statements containing it. Generally, you only need to select a basic operation for a problem to discuss the time complexity of the algorithm. Sometimes you also need to consider multiple basic operations at the same time.
In Web development, the execution time or response time of a function is usually related not only to the server's response and processing capabilities, but also to the interaction time of third-party tools, for example, the connection time of the database and the access time of the data. Therefore, when selecting the original operation, you need to consider all aspects of the application, and take the operation that has the greatest impact on the execution time as the original operation to measure the time complexity of the algorithm. That is to say, programmers need to have a basic understanding of the execution time of important operations when writing code.
Analysis of Time complexity in common programs
Let's take a look at an example. assume that the development language of the Web program is PHP and the DB2 database is used in the background. PHP accesses the database through the PEAR: DB data abstraction layer.
Instance
The database contains STUDENTS (see table 1), Class tables (see table 2), and student orders table SCORES (see table 3 ), the name and class of the student whose score exceeds 90 must be displayed on the Web page.
Table 1. STUDENTS Table
Column name
Description
SID
Student ID
STUNAME
Name
GENDER
Gender
AGE
Age
CLASSID
Class No.
...
Table 2. CLASSES Table
Column name
Description
CLASSID
Class No.
CLASSNAME
Class name
...
Table 3. SCORES Table
Column name
Description
SID
Student ID
COURSE
Subject
SCORE
Score
...
There are usually two ways to solve this problem based on your programming habits (database access operations are represented by PEAR: DB). For more information, see Methods 1 and 2.
[Method 1] perform a joint query on STUDENTS, CLASSES, and SCORES to obtain the student information and class information that meet the conditions at one time. The PHP algorithm is described as follows:
Listing 1. Method 1
The code is as follows:
$ Querystr = "select distinct S. STUNAME as STUNAME, C. CLASSNAME as CLASSNAME ".
"From STUDENTS as S, CLASSES as C, SCORES as R ".
"Where S. SID = R. SID and S. CLASSID = C. CLASSID and R. COURSE = 'math '".
"And R. SCORE> = 90 ";
$ Result = $ db2handle-> query ($ querystr); // obtain data from the database
While ($ row = $ result-> fetchRow (DB_FETCHMODE_ASSOC )){
// Read and display data
Echo "StudentName =". $ row ['stdame']. "\ t ClassName =". $ row ['classname']. "\ n ";
} // Done
[Method 2] find the student ID that meets the conditions in the SCORES table, search for the student name and class code in the STUDENTS table, and obtain the class name in the CLASSES table. The PHP algorithm is described as follows:
Listing 2. Method 2
The code is as follows:
$ Scorestr = "select distinct SID from SCORES where COURSE = 'math' and SCORE> = 90 ";
$ Scoredata = $ db2handle-> query ($ scorestr );
// Obtain the student ID that meets the conditions from the database
While ($ score = $ scoredata-> fetchRow (DB_FETCHMODE_ASSOC )){
// Read the student's student ID and search for the student's name and class number in the STUDENTS table
$ Studentstr = "select STUNAME, CLASSID from STUDENTS where SID = '". $ score ['Sid']. "'";
$ Studata = $ db2handle-> query ($ studentstr );
$ Stu = $ studata-> fetchRow (DB_FETCHMODE_ASSOC );
// Display the student name
Echo "StudentName =". $ stu ['stdame']. "\ t ";
// Read the student's class number and find the name of the student's class in the CLASSES table
$ Classstr = "select CLASSNAME from CLASSES where CLASSID = '". $ stu ['classid']. "'";
$ Classdata = $ db2handle-> query ($ classstr );
$ Class = $ classdata-> fetchRow (DB_FETCHMODE_ASSOC );
// Display the student's class
Echo "CLASSNAME =". $ class ['classname']. "\ n ";
} // End while for getting each student's ID. Done
I believe you will feel familiar with this algorithm. This is also an algorithm widely used by many programmers. Because we are used to directly translating the algorithm logic in our thinking into code, we often have no time or mind to consider the advantages and disadvantages of algorithms. Here we will analyze the time complexity of these two algorithms.
Because the time for the Web server to read and display data is relatively small, it is generally 10 ms, and the time for querying and obtaining data from the DB2 database is ms, and the query data volume increases. Therefore, the database query operation can be used as the original operation to measure the time complexity, and the data volume in the STUDENTS table and SCORES table is used as the problem scale n (generally, the data volume of the CLASSES table is small and relatively stable ).
For Method 1, as the problem scale n increases, the number of accesses to the database is constant 1. Therefore, the time complexity is T (n) = O (1 ). For Method 2, if the SCORES table contains m records that meet the conditions, the number of original operations is m + 1. That is to say, as the data scale n increases, the number of original operations increases linearly. The time complexity is T (n) = O (n ). It can be seen that method 1 has a low time complexity.
So where is the problem with Method 1? This is mainly because Method 1 increases the database load, that is, the execution time of the original operation is greatly affected by the problem scale n. Assume that the number of STUDENTS, CLASSES, and SCORES records is X, Y, and Z respectively. When performing the joint query operation, a matrix of records X * Y * Z will be formed in the database, and then the number of records meeting the conditions will be queried in this matrix, finally, obtain the STUNAME information and CLASSNAME of the record. In this way, increasing data in any table will multiply the number of records in the matrix table.
Use arrays to optimize algorithms
Main idea: when the required data is relatively simple and the data volume is stable, the subscript (Index) of the PHP Array (Array) can be a String, cleverly store data in an array temporarily. In this way, you can quickly obtain the required value through the subscript (Index) to reduce the number of queries to the database, and thus reduce the time complexity of the algorithm.
[Method 3] retrieving the ing between CLASSID and CLASSNAME from the CLASSES table is stored in the ClassArray one-dimensional array, and obtaining the ing between SID, STUNAME, and CLASSID from the STUDENTS table is stored in the StuArray two-dimensional array. Then, find the student ID that meets the conditions in the SCORES table, read the student name and class number from the StuArray, and read the class name from ClassArray. The PHP algorithm is described as follows:
Listing 3. Method 3
The code is as follows:
$ ClassArray = Array ();
$ StuArray = Array ();
$ Classstr = "select CLASSID, CLASSNAME from CLASSES ";
$ Classdata = $ db2handle-> query ($ classstr );
While ($ class = $ classdata-> fetchRow (DB_FETCHMODE_ASSOC )){
// Generate a ClassArray array. the subscript Index is named as CLASSID and the corresponding value is CLASSNAME.
$ ClassArray [$ class ['classid'] = $ class ['classname'];
} // End while $ ClassArray
$ Stustr = "select SID, STUNAME, CLASSID from STUDENTS ";
$ Studata = $ db2handle-> query ($ stustr );
While ($ stu = $ studata-> fetchRow (DB_FETCHMODE_ASSOC )){
// Generate the StuArray array. the subscript Index is named by SID. the corresponding values are STUNAME and CLASSID.
$ StuArray [$ stu ['Sid '] ['stuname'] = $ stu ['stuname'];
$ StuArray [$ stu ['Sid '] ['classid'] = $ stu ['classid '];
} // End while $ StuArray
$ Scorestr = "select distinct SID from SCORES where COURSE = 'math' and SCORE> = 90 ";
$ Scoredata = $ db2handle-> query ($ scorestr );
// Obtain the student ID that meets the conditions from the database
While ($ score = $ scoredata-> fetchRow (DB_FETCHMODE_ASSOC )){
// Read the student ID, the student name from StuArray, and the class name from ClassArray.
Echo "StudentName =". $ StuArray [$ score ['Sid '] ['stuname']. "\ t ";
Echo "CLASSNAME =". $ ClassArray [$ StuArray [$ score ['Sid '] ['classid']. "\ n ";
} // End while for getting each student's ID. Done
The time complexity of the improved method is T (n) = O (1 ). Compared with Method 1, Method 3 does not have to worry about the database query cost multiplied by the increase in the number of records in a table. Compared with Method 2, the time complexity is reduced while the algorithm space complexity is not affected. You can give two birds a second.
Although this optimization method is easy to use, it does not mean that it is omnipotent. The "degree" must be considered during use. If the data volume of the STUDENTS table is large, the consumption of system memory increases when StuArray is generated, and the space complexity of the algorithm is affected. In addition, when the data size is large enough, the main factor affecting the algorithm execution time changes and the original operation needs to be re-selected. For scenarios where the number of STUDENTS tables is large and the number of records in the CLASSES table is small and stable, you can consider using a combination of nested queries and arrays to optimize the algorithm. Method 4 is provided for reference.
[Method 4] retrieving the ing between CLASSID and CLASSNAME from the CLASSES table is stored in the one-dimensional array of ClassArray. The student ID that meets the conditions is queried from the SCORES table as the query condition for the STUDENTS table to obtain the student's STUNAME and CLASSID. Then read the class name from ClassArray. The PHP algorithm is described as follows:
Listing 4. Method 4
The code is as follows:
$ ClassArray = Array ();
$ Classstr = "select CLASSID, CLASSNAME from CLASSES ";
$ Classdata = $ db2handle-> query ($ classstr );
While ($ class = $ classdata-> fetchRow (DB_FETCHMODE_ASSOC )){
// Generate a ClassArray array. the subscript Index is named as CLASSID and the corresponding value is CLASSNAME.
$ ClassArray [$ class ['classid'] = $ class ['classname'];
} // End while $ ClassArray
$ Stustr = "select STUNAME, CLASSID from STUDENTS where SID in ".
"(Select distinct SID from SCORES where COURSE = 'm' and SCORE> = 90 )";
$ Studata = $ db2handle-> query ($ stustr );
// Obtain the qualified student name and class number from the database
While ($ stu = $ studata-> fetchRow (DB_FETCHMODE_ASSOC )){
// Read the student name and the class name from ClassArray
Echo "StudentName =". $ stu ['stdame']. "\ t ";
Echo "CLASSNAME =". $ ClassArray [$ stu ['classid ']. "\ n ";
} // End while for getting each student's Info. Done
Summary
The array technique is referenced in methods 3 and 4, which cleverly reduces the time complexity of the algorithm. In practical applications, the algorithm logic is much more complex, and many factors need to be taken into account for algorithm optimization. The method described in this article is not only applicable to PHP applications. If arrays in programming languages support strings as subscript, we can consider using the method proposed in this article: The subscript of arrays can be used to reduce the time complexity of the algorithm. For programming languages that do not support strings as the underlying targets of arrays, you can consider using hash tables to achieve the same effect.