In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-01-18 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >
Share
Shulou(Shulou.com)05/31 Report--
This article mainly introduces the relevant knowledge of "Python built-in type float source code analysis", the editor shows you the operation process through the actual case, the operation method is simple and fast, and practical. I hope this "Python built-in type float source code analysis" article can help you solve the problem.
1 Review the basics of float 1.1 PyFloatObject
1.2 PyFloat_Type
C source code (only some fields are listed):
PyTypeObject PyFloat_Type = {PyVarObject_HEAD_INIT (& PyType_Type, 0) "float", sizeof (PyFloatObject), 0, (destructor) float_dealloc, / * tp_dealloc * / 0, / * tp_print * / 0, / * tp_getattr * / 0 / * tp_setattr * / 0, / * tp_reserved * / (reprfunc) float_repr, / * tp_repr * / & float_as_number, / * tp_as_number * / 0 / * tp_as_sequence * / 0, / * tp_as_mapping * / (hashfunc) float_hash, / * tp_hash * / 0 / * tp_call * / (reprfunc) float_repr, / * tp_str * / /... 0, / * tp_init * / 0 / * tp_alloc * / float_new, / * tp_new * /}
There is a lot of meta-information about floating-point objects in PyFloat_Type. The key fields include:
Tp_name: save type name, constant float
Tp_dealloc, tp_init, tp_alloc, and tp_new: functions related to object creation and destruction
Tp_repr: a function that generates a syntax string representation
Tp_str: a function that generates a normal string representation
Tp_as_number: numeric operation set
Tp_hash: hash value generating function
1.3 creation of objects
Create an instance object from a type object:
Create an instance object through C API:
PyObject * PyFloat_FromDouble (double fval); PyObject * PyFloat_FromString (PyObject * v); 1.4 destruction of objects
When an object is no longer needed, Python reduces the reference count through Py_DECREF or Py_XDECREF macros
When the reference count drops to 0, Python recycles the object through the _ Py_Dealloc macro. (details on reference counting will be described later)
The _ Py_Dealloc macro actually calls * Py_TYPE (op)-> tp_dealloc, and float_dealloc is called for float:
# define _ Py_Dealloc (op) (\ _ Py_INC_TPFREES (op) _ Py_COUNT_ALLOCS_COMMA\ (* Py_TYPE (op)-> tp_dealloc) ((PyObject *) (op)) 2 Free object cache pool
Problem: floating-point operations involve a large number of temporary object creation and destruction.
Area = pi * r * * 2
This statement first calculates the square of the radius r, and the intermediate result is saved by a temporary object, assuming t, and then calculates the product of pi and t to get the final result and assign it to the variable area
Finally, destroy the temporary object t. Memory needs to be allocated when objects are created, and memory is reclaimed when objects are destroyed. A large number of temporary objects are created and destroyed, which means a large number of memory allocation recycling operations, which is unacceptable.
Therefore, after the floating-point object is destroyed, Python does not rush to reclaim memory, but puts the object into a free linked list. Later, when you need to create a floating-point object, you first take it from the free linked list, saving some of the overhead of allocating memory.
2.1 Free linked list of floating-point objects
C source code:
# ifndef PyFloat_MAXFREELIST#define PyFloat_MAXFREELIST 100#endifstatic int numfree = 0 position static PyFloatObject * free_list = NULL
Source code interpretation:
Free_list variable: pointer to the free chain header node
Numfree variable: maintains the current length of the free list
PyFloat_ MAXFREELIST macro: limit the maximum length of free linked lists to avoid taking up too much memory
To keep it simple, Python uses ob_type fields as next pointers, stringing free objects into linked lists. The float idle list is shown below:
Personal experience:
Such pool technology in Python is used in many places, and in the actual project, it is also a widely used way, you can experience it.
"use ob_type fields as next pointers" can be learned, but also combined with the actual situation: readability, whether you need to save this part of memory, and so on.
2.2 use of idle linked lists
After you have a free linked list, when you need to create a floating-point object, you can remove the free object from the list and save the overhead of applying for memory. Take PyFloat_FromDouble () as an example: (only part of the code is listed)
PyObject * PyFloat_FromDouble (double fval) {PyFloatObject* op = free_list; if (op! = NULL) {free_list = (PyFloatObject*) Py_TYPE (op); numfree--;} else {op = (PyFloatObject*) PyObject_MALLOC (sizeof (PyFloatObject)); if (! op) return PyErr_NoMemory () } / * Inline PyObject_New * / (void) PyObject_INIT (op, & PyFloat_Type); op- > ob_fval = fval; return (PyObject *) op;}
Check whether free_list is empty
If the free_list is not empty, take out the header node for backup, and the free_list points to the second node (see here that the code calls Py_TYPE ()
That is, the ob_type field of op, that is, the second node), and subtract numfree by 1
If free_list is empty, PyObject_MALLOC is called to allocate memory
Finally, op will be set through PyObject_INIT (including modifying ob_type), and then ob_fval will be set to fval
The figure is as follows: (compared with the figure in 2.1, you can see that free_list points to the second node, and the ob_type field of the first node no longer points to the second node, but to the corresponding type object.)
When an object is destroyed, Python caches it in a free linked list for later use. The source code of the float_dealloc function is as follows:
Static voidfloat_dealloc (PyFloatObject * op) {if (PyFloat_CheckExact (op)) {if (numfree > = PyFloat_MAXFREELIST) {PyObject_FREE (op); return;} numfree++; Py_TYPE (op) = (struct _ typeobject *) free_list; free_list = op;} else Py_TYPE (op)-> tp_free ((PyObject *) op);}
If the length of the idle linked list reaches the limit, call PyObject_FREE to reclaim the object memory
If the length of the free list does not reach the limit, insert the object into the head of the free list (here you can review the plug insertion method, hh)
3 other
Question: in the following example, why is the id value of the variable e the same as the destroyed variable pi?
> pi = 3.14 > id (pi) 4565221808 > del pi > e = 2.71 > id (e) 4565221808
Answer: when the 3.14 floating point object is destroyed, its memory is not directly reclaimed, but cached in the free linked list. At this time, the 3.14 floating point object is the free chain header node.
When you create a floating-point object 2.71 and the free list is not empty, take out the header node of the free list and modify the ob_ value to 2.71, so that the id of the two objects is the same.
This is the end of the introduction of "Python built-in type float source code analysis". Thank you for reading. If you want to know more about the industry, you can follow the industry information channel. The editor will update different knowledge points for you every day.
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.