@@ -9124,7 +9124,7 @@ PyObject *
91249124PyUnicode_Join (PyObject * separator , PyObject * seq )
91259125{
91269126 PyObject * sep = NULL ;
9127- Py_ssize_t seplen = 1 ;
9127+ Py_ssize_t seplen ;
91289128 PyObject * res = NULL ; /* the result */
91299129 PyObject * fseq ; /* PySequence_Fast(seq) */
91309130 Py_ssize_t seqlen ; /* len(fseq) -- number of items in sequence */
@@ -9133,6 +9133,10 @@ PyUnicode_Join(PyObject *separator, PyObject *seq)
91339133 Py_ssize_t sz , i , res_offset ;
91349134 Py_UCS4 maxchar ;
91359135 Py_UCS4 item_maxchar ;
9136+ int use_memcpy ;
9137+ unsigned char * res_data = NULL , * sep_data = NULL ;
9138+ PyObject * last_obj ;
9139+ unsigned int kind = 0 ;
91369140
91379141 fseq = PySequence_Fast (seq , "" );
91389142 if (fseq == NULL ) {
@@ -9153,6 +9157,7 @@ PyUnicode_Join(PyObject *separator, PyObject *seq)
91539157 }
91549158
91559159 /* If singleton sequence with an exact Unicode, return that. */
9160+ last_obj = NULL ;
91569161 items = PySequence_Fast_ITEMS (fseq );
91579162 if (seqlen == 1 ) {
91589163 if (PyUnicode_CheckExact (items [0 ])) {
@@ -9161,7 +9166,7 @@ PyUnicode_Join(PyObject *separator, PyObject *seq)
91619166 Py_DECREF (fseq );
91629167 return res ;
91639168 }
9164- sep = NULL ;
9169+ seplen = 0 ;
91659170 maxchar = 0 ;
91669171 }
91679172 else {
@@ -9171,6 +9176,7 @@ PyUnicode_Join(PyObject *separator, PyObject *seq)
91719176 sep = PyUnicode_FromOrdinal (' ' );
91729177 if (!sep )
91739178 goto onError ;
9179+ seplen = 1 ;
91749180 maxchar = 32 ;
91759181 }
91769182 else {
@@ -9190,6 +9196,7 @@ PyUnicode_Join(PyObject *separator, PyObject *seq)
91909196 above case of a blank separator */
91919197 Py_INCREF (sep );
91929198 }
9199+ last_obj = sep ;
91939200 }
91949201
91959202 /* There are at least two things to join, or else we have a subclass
@@ -9198,6 +9205,11 @@ PyUnicode_Join(PyObject *separator, PyObject *seq)
91989205 * need (sz), and see whether all argument are strings.
91999206 */
92009207 sz = 0 ;
9208+ #ifdef Py_DEBUG
9209+ use_memcpy = 0 ;
9210+ #else
9211+ use_memcpy = 1 ;
9212+ #endif
92019213 for (i = 0 ; i < seqlen ; i ++ ) {
92029214 const Py_ssize_t old_sz = sz ;
92039215 item = items [i ];
@@ -9220,28 +9232,63 @@ PyUnicode_Join(PyObject *separator, PyObject *seq)
92209232 "join() result is too long for a Python string" );
92219233 goto onError ;
92229234 }
9235+ if (use_memcpy && last_obj != NULL ) {
9236+ if (PyUnicode_KIND (last_obj ) != PyUnicode_KIND (item ))
9237+ use_memcpy = 0 ;
9238+ }
9239+ last_obj = item ;
92239240 }
92249241
92259242 res = PyUnicode_New (sz , maxchar );
92269243 if (res == NULL )
92279244 goto onError ;
92289245
92299246 /* Catenate everything. */
9247+ #ifdef Py_DEBUG
9248+ use_memcpy = 0 ;
9249+ #else
9250+ if (use_memcpy ) {
9251+ res_data = PyUnicode_1BYTE_DATA (res );
9252+ kind = PyUnicode_KIND (res );
9253+ if (seplen != 0 )
9254+ sep_data = PyUnicode_1BYTE_DATA (sep );
9255+ }
9256+ #endif
92309257 for (i = 0 , res_offset = 0 ; i < seqlen ; ++ i ) {
92319258 Py_ssize_t itemlen ;
92329259 item = items [i ];
92339260 /* Copy item, and maybe the separator. */
92349261 if (i && seplen != 0 ) {
9235- copy_characters (res , res_offset , sep , 0 , seplen );
9236- res_offset += seplen ;
9262+ if (use_memcpy ) {
9263+ Py_MEMCPY (res_data ,
9264+ sep_data ,
9265+ PyUnicode_KIND_SIZE (kind , seplen ));
9266+ res_data += PyUnicode_KIND_SIZE (kind , seplen );
9267+ }
9268+ else {
9269+ copy_characters (res , res_offset , sep , 0 , seplen );
9270+ res_offset += seplen ;
9271+ }
92379272 }
92389273 itemlen = PyUnicode_GET_LENGTH (item );
92399274 if (itemlen != 0 ) {
9240- copy_characters (res , res_offset , item , 0 , itemlen );
9241- res_offset += itemlen ;
9275+ if (use_memcpy ) {
9276+ Py_MEMCPY (res_data ,
9277+ PyUnicode_DATA (item ),
9278+ PyUnicode_KIND_SIZE (kind , itemlen ));
9279+ res_data += PyUnicode_KIND_SIZE (kind , itemlen );
9280+ }
9281+ else {
9282+ copy_characters (res , res_offset , item , 0 , itemlen );
9283+ res_offset += itemlen ;
9284+ }
92429285 }
92439286 }
9244- assert (res_offset == PyUnicode_GET_LENGTH (res ));
9287+ if (use_memcpy )
9288+ assert (res_data == PyUnicode_1BYTE_DATA (res )
9289+ + PyUnicode_KIND_SIZE (kind , PyUnicode_GET_LENGTH (res )));
9290+ else
9291+ assert (res_offset == PyUnicode_GET_LENGTH (res ));
92459292
92469293 Py_DECREF (fseq );
92479294 Py_XDECREF (sep );
0 commit comments