Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
C
cython
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Gwenaël Samain
cython
Commits
0897f269
Commit
0897f269
authored
Mar 26, 2015
by
Stefan Behnel
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
extend PyLong optimisations to larger negative numbers, enable it also in Py2.7
parent
89fec0ac
Changes
6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
48 additions
and
51 deletions
+48
-51
CHANGES.rst
CHANGES.rst
+2
-0
Cython/Compiler/ModuleNode.py
Cython/Compiler/ModuleNode.py
+0
-20
Cython/Utility/ModuleSetupCode.c
Cython/Utility/ModuleSetupCode.c
+4
-0
Cython/Utility/Optimize.c
Cython/Utility/Optimize.c
+17
-15
Cython/Utility/StringTools.c
Cython/Utility/StringTools.c
+1
-2
Cython/Utility/TypeConversion.c
Cython/Utility/TypeConversion.c
+24
-14
No files found.
CHANGES.rst
View file @
0897f269
...
...
@@ -15,6 +15,8 @@ Features added
* Tracing is supported in ``nogil`` functions/sections and module init code.
* Optimisations for PyLong are enabled in Py2.7 (not only Py3.x).
* Adding/subtracting constant Python floats and small integers is faster.
* Binary and/or/xor operations and modulus with small constant Python integers
...
...
Cython/Compiler/ModuleNode.py
View file @
0897f269
...
...
@@ -571,26 +571,6 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
code
.
putln
(
""
)
code
.
putln
(
"#define PY_SSIZE_T_CLEAN"
)
# sizeof(PyLongObject.ob_digit[0]) may have been determined dynamically
# at compile time in CPython, in which case we can't know the correct
# storage size for an installed system. We can rely on it only if
# pyconfig.h defines it statically, i.e. if it was set by "configure".
# Once we include "Python.h", it will come up with its own idea about
# a suitable value, which may or may not match the real one.
code
.
putln
(
"#ifndef CYTHON_USE_PYLONG_INTERNALS"
)
code
.
putln
(
"#ifdef PYLONG_BITS_IN_DIGIT"
)
# assume it's an incorrect left-over
code
.
putln
(
"#define CYTHON_USE_PYLONG_INTERNALS 0"
)
code
.
putln
(
"#else"
)
code
.
putln
(
'#include "pyconfig.h"'
)
code
.
putln
(
"#ifdef PYLONG_BITS_IN_DIGIT"
)
code
.
putln
(
"#define CYTHON_USE_PYLONG_INTERNALS 1"
)
code
.
putln
(
"#else"
)
code
.
putln
(
"#define CYTHON_USE_PYLONG_INTERNALS 0"
)
code
.
putln
(
"#endif"
)
code
.
putln
(
"#endif"
)
code
.
putln
(
"#endif"
)
for
filename
in
env
.
python_include_files
:
code
.
putln
(
'#include "%s"'
%
filename
)
code
.
putln
(
"#ifndef Py_PYTHON_H"
)
...
...
Cython/Utility/ModuleSetupCode.c
View file @
0897f269
...
...
@@ -40,6 +40,10 @@
#define CYTHON_COMPILING_IN_CPYTHON 1
#endif
#if !defined(CYTHON_USE_PYLONG_INTERNALS) && CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x02070000
#define CYTHON_USE_PYLONG_INTERNALS 1
#endif
#if CYTHON_COMPILING_IN_PYPY && PY_VERSION_HEX < 0x02070600 && !defined(Py_OptimizeFlag)
#define Py_OptimizeFlag 0
#endif
...
...
Cython/Utility/Optimize.c
View file @
0897f269
...
...
@@ -448,7 +448,7 @@ static PyObject* __Pyx__PyNumber_PowerOf2(PyObject *two, PyObject *exp, PyObject
}
else
#endif
if
(
likely
(
PyLong_CheckExact
(
exp
)))
{
#if CYTHON_
COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3 && CYTHON_
USE_PYLONG_INTERNALS
#if CYTHON_USE_PYLONG_INTERNALS
switch
(
Py_SIZE
(
exp
))
{
case
0
:
shiftby
=
0
;
break
;
case
1
:
shiftby
=
((
PyLongObject
*
)
exp
)
->
ob_digit
[
0
];
break
;
...
...
@@ -528,21 +528,25 @@ static PyObject* __Pyx_PyInt_{{op}}{{order}}(PyObject *op1, PyObject *op2, CYTHO
}
#endif
#if CYTHON_
COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3 && CYTHON_
USE_PYLONG_INTERNALS
#if CYTHON_USE_PYLONG_INTERNALS
if
(
likely
(
PyLong_CheckExact
({{
pyval
}})))
{
const
long
{{
'a'
if
order
==
'
CObj
'
else
'b'
}}
=
intval
;
long
x
,
{{
ival
}};
const
Py_ssize_t
size
=
Py_SIZE
({{
pyval
}});
switch
(
size
)
{
case
0
:
{{
ival
}}
=
0
;
break
;
{{
if
c_op
!=
'%'
}}
case
-
1
:
{{
ival
}}
=
-
(
sdigit
)((
PyLongObject
*
){{
pyval
}})
->
ob_digit
[
0
];
break
;
{{
else
}}
case
-
1
:
// fall through to positive calculation for '%'
{{
endif
}}
case
-
1
:
{{
if
c_op
!=
'%'
}}
{{
ival
}}
=
-
(
sdigit
)((
PyLongObject
*
){{
pyval
}})
->
ob_digit
[
0
];
break
;
{{
endif
}}
// fall through to positive calculation for '%'
case
1
:
{{
ival
}}
=
((
PyLongObject
*
){{
pyval
}})
->
ob_digit
[
0
];
break
;
case
-
2
:
case
-
2
:
{{
if
c_op
!=
'%'
}}
if
(
8
*
sizeof
(
long
)
-
1
>
2
*
PyLong_SHIFT
)
{
{{
ival
}}
=
-
(
long
)
((((
unsigned
long
)((
PyLongObject
*
){{
pyval
}})
->
ob_digit
[
1
])
<<
PyLong_SHIFT
)
|
((
PyLongObject
*
){{
pyval
}})
->
ob_digit
[
0
]);
break
;
}
{{
endif
}}
// fall through to positive calculation for '%'
case
2
:
if
(
8
*
sizeof
(
long
)
-
1
>
2
*
PyLong_SHIFT
)
{
{{
ival
}}
=
(
long
)
((((
unsigned
long
)((
PyLongObject
*
){{
pyval
}})
->
ob_digit
[
1
])
<<
PyLong_SHIFT
)
|
((
PyLongObject
*
){{
pyval
}})
->
ob_digit
[
0
]);
...
...
@@ -552,11 +556,9 @@ static PyObject* __Pyx_PyInt_{{op}}{{order}}(PyObject *op1, PyObject *op2, CYTHO
default:
return
PyLong_Type
.
tp_as_number
->
nb_
{{
op
.
lower
()}}(
op1
,
op2
);
}
{{
if
c_op
==
'%'
}}
if
(
unlikely
(
size
<
0
))
{
x
=
(
-
a
)
%
b
;
if
(
x
)
x
=
b
-
x
;
}
else
{
x
=
a
%
b
;
x
=
a
%
b
;
if
(
unlikely
(
size
<
0
)
&&
x
)
{
x
=
b
-
x
;
}
{{
else
}}
x
=
a
{{
c_op
}}
b
;
...
...
@@ -612,7 +614,7 @@ static PyObject* __Pyx_PyFloat_{{op}}{{order}}(PyObject *op1, PyObject *op2, dou
#endif
if
(
likely
(
PyLong_CheckExact
({{
pyval
}})))
{
#if CYTHON_
COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3 && CYTHON_
USE_PYLONG_INTERNALS
#if CYTHON_USE_PYLONG_INTERNALS
const
Py_ssize_t
size
=
Py_SIZE
({{
pyval
}});
switch
(
size
)
{
case
-
1
:
{{
fval
}}
=
-
(
double
)((
PyLongObject
*
){{
pyval
}})
->
ob_digit
[
0
];
break
;
...
...
Cython/Utility/StringTools.c
View file @
0897f269
...
...
@@ -721,7 +721,7 @@ static CYTHON_INLINE int __Pyx_PyByteArray_AppendObject(PyObject* bytearray, PyO
}
ival
=
(
unsigned
char
)
(
PyString_AS_STRING
(
value
)[
0
]);
}
else
#e
lse
#e
ndif
#if CYTHON_USE_PYLONG_INTERNALS
if
(
likely
(
PyLong_CheckExact
(
value
))
&&
likely
(
Py_SIZE
(
value
)
==
1
||
Py_SIZE
(
value
)
==
0
))
{
if
(
Py_SIZE
(
value
)
==
0
)
{
...
...
@@ -731,7 +731,6 @@ static CYTHON_INLINE int __Pyx_PyByteArray_AppendObject(PyObject* bytearray, PyO
if
(
unlikely
(
ival
>
255
))
goto
bad_range
;
}
}
else
#endif
#endif
{
// CPython calls PyNumber_Index() internally
...
...
Cython/Utility/TypeConversion.c
View file @
0897f269
...
...
@@ -292,16 +292,21 @@ static CYTHON_INLINE Py_ssize_t __Pyx_PyIndex_AsSsize_t(PyObject* b) {
}
#endif
if
(
likely
(
PyLong_CheckExact
(
b
)))
{
#if CYTHON_
COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3 && CYTHON_
USE_PYLONG_INTERNALS
#if CYTHON_USE_PYLONG_INTERNALS
switch
(
Py_SIZE
(
b
))
{
case
-
1
:
return
-
(
sdigit
)((
PyLongObject
*
)
b
)
->
ob_digit
[
0
];
case
0
:
return
0
;
case
1
:
return
((
PyLongObject
*
)
b
)
->
ob_digit
[
0
];
case
-
1
:
return
-
(
sdigit
)((
PyLongObject
*
)
b
)
->
ob_digit
[
0
];
case
2
:
if
(
8
*
sizeof
(
Py_ssize_t
)
>
2
*
PyLong_SHIFT
)
{
return
(
Py_ssize_t
)
((((
size_t
)((
PyLongObject
*
)
b
)
->
ob_digit
[
1
])
<<
PyLong_SHIFT
)
|
((
PyLongObject
*
)
b
)
->
ob_digit
[
0
]);
}
break
;
case
-
2
:
if
(
8
*
sizeof
(
Py_ssize_t
)
>
2
*
PyLong_SHIFT
)
{
return
-
(
Py_ssize_t
)
((((
size_t
)((
PyLongObject
*
)
b
)
->
ob_digit
[
1
])
<<
PyLong_SHIFT
)
|
((
PyLongObject
*
)
b
)
->
ob_digit
[
0
]);
}
break
;
}
#endif
return
PyLong_AsSsize_t
(
b
);
...
...
@@ -522,10 +527,8 @@ static CYTHON_INLINE PyObject* {{TO_PY_FUNCTION}}({{TYPE}} value) {
/////////////// PyLongInternals ///////////////
#if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3
#if CYTHON_USE_PYLONG_INTERNALS
#if CYTHON_USE_PYLONG_INTERNALS
#include "longintrepr.h"
#endif
#endif
...
...
@@ -555,19 +558,19 @@ static CYTHON_INLINE {{TYPE}} {{FROM_PY_FUNCTION}}(PyObject *x) {
#endif
if
(
likely
(
PyLong_Check
(
x
)))
{
if
(
is_unsigned
)
{
#if CYTHON_COMPILING_IN_CPYTHON
#if PY_MAJOR_VERSION >= 3 && CYTHON_USE_PYLONG_INTERNALS
#if CYTHON_USE_PYLONG_INTERNALS
switch
(
Py_SIZE
(
x
))
{
case
0
:
return
0
;
case
1
:
__PYX_VERIFY_RETURN_INT
({{
TYPE
}},
digit
,
((
PyLongObject
*
)
x
)
->
ob_digit
[
0
])
;
case
1
:
__PYX_VERIFY_RETURN_INT
({{
TYPE
}},
digit
,
((
PyLongObject
*
)
x
)
->
ob_digit
[
0
])
case
2
:
if
((
8
*
sizeof
({{
TYPE
}})
>
PyLong_SHIFT
)
&&
(
8
*
sizeof
(
unsigned
long
)
>
2
*
PyLong_SHIFT
))
{
__PYX_VERIFY_RETURN_INT
({{
TYPE
}},
unsigned
long
,
(((
unsigned
long
)((
PyLongObject
*
)
x
)
->
ob_digit
[
1
])
<<
PyLong_SHIFT
)
|
((
PyLongObject
*
)
x
)
->
ob_digit
[
0
])
;
(((
unsigned
long
)((
PyLongObject
*
)
x
)
->
ob_digit
[
1
])
<<
PyLong_SHIFT
)
|
((
PyLongObject
*
)
x
)
->
ob_digit
[
0
])
}
break
;
}
#endif
#endif
#if CYTHON_COMPILING_IN_CPYTHON
if
(
unlikely
(
Py_SIZE
(
x
)
<
0
))
{
goto
raise_neg_overflow
;
}
...
...
@@ -578,15 +581,22 @@ static CYTHON_INLINE {{TYPE}} {{FROM_PY_FUNCTION}}(PyObject *x) {
__PYX_VERIFY_RETURN_INT
({{
TYPE
}},
unsigned
long
long
,
PyLong_AsUnsignedLongLong
(
x
))
}
}
else
{
#if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3 && CYTHON_USE_PYLONG_INTERNALS
// signed
#if CYTHON_USE_PYLONG_INTERNALS
switch
(
Py_SIZE
(
x
))
{
case
0
:
return
0
;
case
-
1
:
__PYX_VERIFY_RETURN_INT
({{
TYPE
}},
sdigit
,
-
(
sdigit
)
((
PyLongObject
*
)
x
)
->
ob_digit
[
0
])
;
case
1
:
__PYX_VERIFY_RETURN_INT
({{
TYPE
}},
digit
,
+
(((
PyLongObject
*
)
x
)
->
ob_digit
[
0
]))
;
case
-
1
:
__PYX_VERIFY_RETURN_INT
({{
TYPE
}},
sdigit
,
-
(
sdigit
)
((
PyLongObject
*
)
x
)
->
ob_digit
[
0
])
case
1
:
__PYX_VERIFY_RETURN_INT
({{
TYPE
}},
digit
,
+
(((
PyLongObject
*
)
x
)
->
ob_digit
[
0
]))
case
2
:
if
((
8
*
sizeof
({{
TYPE
}})
>
PyLong_SHIFT
)
&&
(
8
*
sizeof
(
unsigned
long
)
>
2
*
PyLong_SHIFT
))
{
__PYX_VERIFY_RETURN_INT
({{
TYPE
}},
unsigned
long
,
(((
unsigned
long
)((
PyLongObject
*
)
x
)
->
ob_digit
[
1
])
<<
PyLong_SHIFT
)
|
((
PyLongObject
*
)
x
)
->
ob_digit
[
0
]);
(((
unsigned
long
)((
PyLongObject
*
)
x
)
->
ob_digit
[
1
])
<<
PyLong_SHIFT
)
|
((
PyLongObject
*
)
x
)
->
ob_digit
[
0
])
}
break
;
case
-
2
:
if
((
8
*
sizeof
({{
TYPE
}})
>
2
*
PyLong_SHIFT
)
&&
(
8
*
sizeof
(
unsigned
long
)
>
2
*
PyLong_SHIFT
))
{
__PYX_VERIFY_RETURN_INT
({{
TYPE
}},
long
,
-
(
long
)
(((
unsigned
long
)((
PyLongObject
*
)
x
)
->
ob_digit
[
1
])
<<
PyLong_SHIFT
)
|
((
PyLongObject
*
)
x
)
->
ob_digit
[
0
])
}
break
;
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment