Use Psyco to speed up Python running, psycopython

Source: Internet
Author: User
Tags string methods

Use Psyco to speed up Python running, psycopython

Psyco strictly operates during Python runtime. That is to say, the Python source code is compiled into bytecode through the python command, and the method used is exactly the same as before (except for several import statements and function calls added to call Psyco ). However, when the Python interpreter runs the application, Psyco checks from time to see if it can replace regular Python Bytecode operations with dedicated machine code. This kind of specialized compilation is very similar to the operations performed by the Java instant Compiler (at least) and is architecture-specific. Until now, Psyco can only be used in the i386 CPU architecture. The magic of Psyco is that you can use the Python code you have been writing (Exactly the same !), But it can run faster.

How does Psyco work?

To fully understand Psyco, you may need to have a good understanding of the eval_frame () function and i386 assembly language of the Python interpreter. Unfortunately, I am not allowed to give expert comments on any of them-but I think I can give a rough overview of Psyco.
In conventional Python, The eval_frame () function is an internal loop of the Python interpreter. The eval_frame () function mainly looks at the current bytecode in the execution context and switches the control outward to a function suitable for implementing this bytecode. The details of what functions are supported usually depend on the status of various Python objects stored in the memory. Simply put, adding Python objects "2" and "3" and adding objects "5" and "6" produce different results, but both operations are distributed in a similar way.
Psyco replaces the eval_frame () function with a compound evaluation unit. Psyco has several methods to improve Python operations. First, Psyco compiles the operation into a slightly optimized machine code. Because the work to be done by the machine code is the same as that of the Python assignment function, it only has some improvements. In addition, the "special" content in the Psyco compilation is not only about the selection of Python bytecode, but also about the variable values known in the execution context. For example, in code similar to the following, variable x is known during the cycle duration:

Copy codeThe Code is as follows:
X = 5
L = []
For I in range (1000 ):
L. append (x * I)

The optimized version of the code in this section does not need to use "x variable/object content" to multiply each I. In contrast, simply multiply 5 by each I with less overhead, this step of searching/indirect reference is omitted.
In addition to creating i386-specific code for small operations, Psyco caches this compiled machine code for future reuse. If Psyco identifies a specific operation that is the same as the previously executed ("specialized") operation, it can rely on this high-speed cache code without re-compiling the code segment. This saves some time.
However, the reason why Psyco really saves time is that Psyco divides the operation into three different levels. For Psyco, there are "RunTime", "compile-time", and "virtual time" variables. Psyco increases and reduces the variable level as needed. The runtime variable is only the original bytecode and object structure processed by the regular Python interpreter. Once Psyco compiles the operation into a machine code, the variables will be expressed in the machine registers and memory locations that can be accessed directly.
The most interesting level is the virtual time variable. Internally, a Python variable is a complete structure composed of many Members-even if the object represents only one integer. Psyco Virtual Variables represent Python objects that may be built when needed, but the details of these objects are ignored before they become Python objects. For example, consider the following assignment:
X = 15*(14 + (13-(12/11 )))
Standard Python builds and destroys many objects to calculate this value. Construct a complete integer object to save the value (12/11); then "pull" a value from the structure of the temporary object and use it to calculate the new temporary object (13-PyInt ). While Psyco skips these objects and only calculates these values, because it knows that "if needed", you can create an object from the value.

Use Psyco

It is relatively difficult to explain Psyco, but it is very easy to use Psyco. Basically, all the content is to tell the Psyco module which function/method should be "specialized ". No Python function or class code needs to be changed.
There are several ways to specify what Psyco should do. The shotgun method allows you to use Psyco in real time everywhere. To do this, place the following lines at the top of the module:

Copy codeThe Code is as follows:
Import psyco; psyco. jit ()
From psyco. classes import *

The first line tells Psyco to "exert its magic" on all global functions ". The second line (in Python 2.2 and later versions) tells Psyco to perform the same operation on class methods. To more accurately determine the behavior of Psyco, you can use the following command:
Psyco. bind (somefunc) # or method, class
Newname = psyco. proxy (func)
The second method uses func as a standard Python function, but optimizes the call involving newname. In almost all cases except testing and debugging, you will use the psyco. bind () format.

Psyco Performance

Despite the magic of Psyco, using it still requires a bit of thinking and testing. It is important to understand that Psyco is useful for processing blocks with multiple loops, and it knows how to optimize operations involving integers and floating points. For non-circular functions and other types of object operations, Psyco only increases the overhead of analysis and internal compilation. Moreover, for applications that contain a large number of functions and classes, enabling Psyco throughout the application adds a lot of burden to machine code compilation and memory usage for this high-speed cache. It is much better to selectively bind functions that can maximize the benefits of Psyco optimization.
I started my testing process in a very naive way. I have only considered the applications that I recently run but have not yet considered acceleration. The first example is to convert the Text Processing in Python into a LaTeX format Text operator. This application uses some string methods, some regular expressions, and some program logic that is mainly driven by regular expressions and string matching. In fact, it is a bad choice to use it as a test candidate for Psyco, but I still use it, so that's the start.
In the first test, I added psyco. jit () to the top of the script. This is not a hard task. Unfortunately, the results (unexpected) were disappointing. It took 8.5 seconds for the original script to run. After Psyco's "acceleration", it would take about 12 seconds to run. Really bad! I guess it is probably because the startup overhead required for instant compilation slows down the running time. So next I try to process a larger input file (consisting of multiple copies of the original input file ). This was a small success, and the running time was reduced from about 120 seconds to 110 seconds. The acceleration effect is consistent several times, but the effect is not significant.
This is the second test of candidate items. I only added psyco. bind (main), instead of adding a total psyco. jit () is called because the main () function does need to be cyclically multiple times (but only uses the least integer operation ). The result here is nominal better than the previous one. This method reduces the normal running time by a few seconds and several seconds in the case of a large input version. But there are still no notable results introduced (but there is no harm ).

To perform a more appropriate Psyco test, I found some neural network code I wrote in my previous article (refer to "references "). This "code_recognizer" application can be trained to identify the possible distribution of different ASCII values written in different programming languages. Something like this may be useful in predicting the file type (for example, the lost Network Information Package); but what about "training, code is actually completely universal-it can easily learn to recognize faces, sounds, or tidal patterns. In any case, the "code reader" is based on the Python library bpnn, And the Psyco 4.0 distribution edition also contains (in the form of correction) This library as a test case. In this article, the "code reader" should be noted that it has done a lot of floating point operation cycles and took a long time to run. Here we have a good candidate case for Psyco testing.
After using Psyco for a while, I created some details about the usage of Psyco. For such applications with only a few classes and functions, there is no big difference between using instant binding or target binding. However, the best result is that the optimization class can still be improved by several percentage points through selective binding. However, it is important to understand the scope of Psyco binding.
The code_recognizer.py script includes the following rows:

Import NN from bpnn
Class NN2 (NN ):
# Customized output methods, math core inherited
That is to say, from the perspective of Psyco, interesting things are in the class bpnn. NN. Adding psyco. jit () or psyco. bind (NN2) to the code_recognizer.py script does not play any role. To optimize Psyco, you need to add psyco. bind (NN) to code_recognizer.py or psyco. jit () to bpnn. py. Contrary to what you may assume, instant optimization does not occur when you create an instance or when the method is running, but within the scope of the defined class. In addition, binding a derived class does not specialize in the methods it inherits from other places.
Once you find the appropriate details of the Psyco binding, the acceleration effect is quite obvious. Use the same test cases and training methods (500 training modes and 1000 training iterations) provided in reference articles ), the neural network training time was reduced from about 2000 seconds to about 600 seconds-more than three times faster. The number of iterations is reduced to 10, and the acceleration factor is reduced proportionally (but the recognition capability of the neural network is ineffective). The intermediate values of iterations also change.
I found that using two lines of new code can reduce the running time from more than half an hour to about 10 minutes, with remarkable results. Such acceleration may still be slower than similar applications written in C, and it must be 100 times slower than the acceleration reflected by several independent Psyco test cases. However, such applications are quite "real" and these improvements are significant enough in many environments.

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.