Skip to content
Projeler
Gruplar
Parçacıklar
Yardım
Yükleniyor...
Oturum aç / Kaydol
Gezinmeyi değiştir
C
cpython
Proje
Proje
Ayrıntılar
Etkinlik
Cycle Analytics
Depo (repository)
Depo (repository)
Dosyalar
Kayıtlar (commit)
Dallar (branch)
Etiketler
Katkıda bulunanlar
Grafik
Karşılaştır
Grafikler
Konular (issue)
0
Konular (issue)
0
Liste
Pano
Etiketler
Kilometre Taşları
Birleştirme (merge) Talepleri
0
Birleştirme (merge) Talepleri
0
CI / CD
CI / CD
İş akışları (pipeline)
İşler
Zamanlamalar
Grafikler
Paketler
Paketler
Wiki
Wiki
Parçacıklar
Parçacıklar
Üyeler
Üyeler
Collapse sidebar
Close sidebar
Etkinlik
Grafik
Grafikler
Yeni bir konu (issue) oluştur
İşler
Kayıtlar (commit)
Konu (issue) Panoları
Kenar çubuğunu aç
Batuhan Osman TASKAYA
cpython
Commits
7c17e230
Kaydet (Commit)
7c17e230
authored
Agu 17, 2017
tarafından
Adrian Wielgosik
Kaydeden (comit)
Antoine Pitrou
Agu 17, 2017
Dosyalara gözat
Seçenekler
Dosyalara Gözat
İndir
Eposta Yamaları
Sade Fark
bpo-24700: Add a fast path for comparing array.array of equal type (#3009)
üst
ee84a608
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
79 additions
and
15 deletions
+79
-15
test_array.py
Lib/test/test_array.py
+10
-0
2017-08-08-15-14-34.bpo-24700.44mvNV.rst
...S.d/next/Library/2017-08-08-15-14-34.bpo-24700.44mvNV.rst
+3
-0
arraymodule.c
Modules/arraymodule.c
+66
-15
No files found.
Lib/test/test_array.py
Dosyayı görüntüle @
7c17e230
...
...
@@ -1342,6 +1342,16 @@ class FPTest(NumberTest):
def
assertEntryEqual
(
self
,
entry1
,
entry2
):
self
.
assertAlmostEqual
(
entry1
,
entry2
)
def
test_nan
(
self
):
a
=
array
.
array
(
self
.
typecode
,
[
float
(
'nan'
)])
b
=
array
.
array
(
self
.
typecode
,
[
float
(
'nan'
)])
self
.
assertIs
(
a
!=
b
,
True
)
self
.
assertIs
(
a
==
b
,
False
)
self
.
assertIs
(
a
>
b
,
False
)
self
.
assertIs
(
a
>=
b
,
False
)
self
.
assertIs
(
a
<
b
,
False
)
self
.
assertIs
(
a
<=
b
,
False
)
def
test_byteswap
(
self
):
a
=
array
.
array
(
self
.
typecode
,
self
.
example
)
self
.
assertRaises
(
TypeError
,
a
.
byteswap
,
42
)
...
...
Misc/NEWS.d/next/Library/2017-08-08-15-14-34.bpo-24700.44mvNV.rst
0 → 100644
Dosyayı görüntüle @
7c17e230
Optimize array.array comparison. It is now from 10x up to 70x faster when
comparing arrays holding values of the same integer type.
\ No newline at end of file
Modules/arraymodule.c
Dosyayı görüntüle @
7c17e230
...
...
@@ -31,6 +31,7 @@ struct arraydescr {
int
itemsize
;
PyObject
*
(
*
getitem
)(
struct
arrayobject
*
,
Py_ssize_t
);
int
(
*
setitem
)(
struct
arrayobject
*
,
Py_ssize_t
,
PyObject
*
);
int
(
*
compareitems
)(
const
void
*
,
const
void
*
,
Py_ssize_t
);
const
char
*
formats
;
int
is_integer_type
;
int
is_signed
;
...
...
@@ -518,6 +519,28 @@ d_setitem(arrayobject *ap, Py_ssize_t i, PyObject *v)
return
0
;
}
#define DEFINE_COMPAREITEMS(code, type) \
static int \
code##_compareitems(const void *lhs, const void *rhs, Py_ssize_t length) \
{ \
const type *a = lhs, *b = rhs; \
for (Py_ssize_t i = 0; i < length; ++i) \
if (a[i] != b[i]) \
return a[i] < b[i] ? -1 : 1; \
return 0; \
}
DEFINE_COMPAREITEMS
(
b
,
signed
char
)
DEFINE_COMPAREITEMS
(
BB
,
unsigned
char
)
DEFINE_COMPAREITEMS
(
u
,
Py_UNICODE
)
DEFINE_COMPAREITEMS
(
h
,
short
)
DEFINE_COMPAREITEMS
(
HH
,
unsigned
short
)
DEFINE_COMPAREITEMS
(
i
,
int
)
DEFINE_COMPAREITEMS
(
II
,
unsigned
int
)
DEFINE_COMPAREITEMS
(
l
,
long
)
DEFINE_COMPAREITEMS
(
LL
,
unsigned
long
)
DEFINE_COMPAREITEMS
(
q
,
long
long
)
DEFINE_COMPAREITEMS
(
QQ
,
unsigned
long
long
)
/* Description of types.
*
...
...
@@ -525,19 +548,19 @@ d_setitem(arrayobject *ap, Py_ssize_t i, PyObject *v)
* typecode.
*/
static
const
struct
arraydescr
descriptors
[]
=
{
{
'b'
,
1
,
b_getitem
,
b_setitem
,
"b"
,
1
,
1
},
{
'B'
,
1
,
BB_getitem
,
BB_setitem
,
"B"
,
1
,
0
},
{
'u'
,
sizeof
(
Py_UNICODE
),
u_getitem
,
u_setitem
,
"u"
,
0
,
0
},
{
'h'
,
sizeof
(
short
),
h_getitem
,
h_setitem
,
"h"
,
1
,
1
},
{
'H'
,
sizeof
(
short
),
HH_getitem
,
HH_setitem
,
"H"
,
1
,
0
},
{
'i'
,
sizeof
(
int
),
i_getitem
,
i_setitem
,
"i"
,
1
,
1
},
{
'I'
,
sizeof
(
int
),
II_getitem
,
II_setitem
,
"I"
,
1
,
0
},
{
'l'
,
sizeof
(
long
),
l_getitem
,
l_setitem
,
"l"
,
1
,
1
},
{
'L'
,
sizeof
(
long
),
LL_getitem
,
LL_setitem
,
"L"
,
1
,
0
},
{
'q'
,
sizeof
(
long
long
),
q_getitem
,
q_setitem
,
"q"
,
1
,
1
},
{
'Q'
,
sizeof
(
long
long
),
QQ_getitem
,
QQ_setitem
,
"Q"
,
1
,
0
},
{
'f'
,
sizeof
(
float
),
f_getitem
,
f_setitem
,
"f"
,
0
,
0
},
{
'd'
,
sizeof
(
double
),
d_getitem
,
d_setitem
,
"d"
,
0
,
0
},
{
'b'
,
1
,
b_getitem
,
b_setitem
,
b_compareitems
,
"b"
,
1
,
1
},
{
'B'
,
1
,
BB_getitem
,
BB_setitem
,
BB_compareitems
,
"B"
,
1
,
0
},
{
'u'
,
sizeof
(
Py_UNICODE
),
u_getitem
,
u_setitem
,
u_compareitems
,
"u"
,
0
,
0
},
{
'h'
,
sizeof
(
short
),
h_getitem
,
h_setitem
,
h_compareitems
,
"h"
,
1
,
1
},
{
'H'
,
sizeof
(
short
),
HH_getitem
,
HH_setitem
,
HH_compareitems
,
"H"
,
1
,
0
},
{
'i'
,
sizeof
(
int
),
i_getitem
,
i_setitem
,
i_compareitems
,
"i"
,
1
,
1
},
{
'I'
,
sizeof
(
int
),
II_getitem
,
II_setitem
,
II_compareitems
,
"I"
,
1
,
0
},
{
'l'
,
sizeof
(
long
),
l_getitem
,
l_setitem
,
l_compareitems
,
"l"
,
1
,
1
},
{
'L'
,
sizeof
(
long
),
LL_getitem
,
LL_setitem
,
LL_compareitems
,
"L"
,
1
,
0
},
{
'q'
,
sizeof
(
long
long
),
q_getitem
,
q_setitem
,
q_compareitems
,
"q"
,
1
,
1
},
{
'Q'
,
sizeof
(
long
long
),
QQ_getitem
,
QQ_setitem
,
QQ_compareitems
,
"Q"
,
1
,
0
},
{
'f'
,
sizeof
(
float
),
f_getitem
,
f_setitem
,
NULL
,
"f"
,
0
,
0
},
{
'd'
,
sizeof
(
double
),
d_getitem
,
d_setitem
,
NULL
,
"d"
,
0
,
0
},
{
'\0'
,
0
,
0
,
0
,
0
,
0
,
0
}
/* Sentinel */
};
...
...
@@ -664,6 +687,31 @@ array_richcompare(PyObject *v, PyObject *w, int op)
return
res
;
}
if
(
va
->
ob_descr
==
wa
->
ob_descr
&&
va
->
ob_descr
->
compareitems
!=
NULL
)
{
/* Fast path:
arrays with same types can have their buffers compared directly */
Py_ssize_t
common_length
=
Py_MIN
(
Py_SIZE
(
va
),
Py_SIZE
(
wa
));
int
result
=
va
->
ob_descr
->
compareitems
(
va
->
ob_item
,
wa
->
ob_item
,
common_length
);
if
(
result
==
0
)
goto
compare_sizes
;
int
cmp
;
switch
(
op
)
{
case
Py_LT
:
cmp
=
result
<
0
;
break
;
case
Py_LE
:
cmp
=
result
<=
0
;
break
;
case
Py_EQ
:
cmp
=
result
==
0
;
break
;
case
Py_NE
:
cmp
=
result
!=
0
;
break
;
case
Py_GT
:
cmp
=
result
>
0
;
break
;
case
Py_GE
:
cmp
=
result
>=
0
;
break
;
default:
return
NULL
;
/* cannot happen */
}
PyObject
*
res
=
cmp
?
Py_True
:
Py_False
;
Py_INCREF
(
res
);
return
res
;
}
/* Search for the first index where items are different */
k
=
1
;
for
(
i
=
0
;
i
<
Py_SIZE
(
va
)
&&
i
<
Py_SIZE
(
wa
);
i
++
)
{
...
...
@@ -685,14 +733,17 @@ array_richcompare(PyObject *v, PyObject *w, int op)
if
(
k
)
{
/* No more items to compare -- compare sizes */
compare_sizes:
;
Py_ssize_t
vs
=
Py_SIZE
(
va
);
Py_ssize_t
ws
=
Py_SIZE
(
wa
);
int
cmp
;
switch
(
op
)
{
case
Py_LT
:
cmp
=
vs
<
ws
;
break
;
case
Py_LE
:
cmp
=
vs
<=
ws
;
break
;
case
Py_EQ
:
cmp
=
vs
==
ws
;
break
;
case
Py_NE
:
cmp
=
vs
!=
ws
;
break
;
/* If the lengths were not equal,
the earlier fast-path check would have caught that. */
case
Py_EQ
:
assert
(
vs
==
ws
);
cmp
=
1
;
break
;
case
Py_NE
:
assert
(
vs
==
ws
);
cmp
=
0
;
break
;
case
Py_GT
:
cmp
=
vs
>
ws
;
break
;
case
Py_GE
:
cmp
=
vs
>=
ws
;
break
;
default:
return
NULL
;
/* cannot happen */
...
...
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