반응형
다음과는 달리 Python에서 한 문자열을 다른 문자열에 추가하는 효율적인 방법을 원합니다.
var1 = "foo"
var2 = "bar"
var3 = var1 + var2
사용할 좋은 기본 제공 방법이 있습니까?
해결 방법
문자열에 대한 참조가 하나만 있고 다른 문자열을 끝에 연결하는 경우 CPython은 이제 특수한 경우에 해당 문자열을 제자리에서 확장하려고합니다.
최종 결과는 작업이 O (n)으로 상각된다는 것입니다.
예 :
s = ""
for i in range(n):
s+=str(i)
예전에는 O (n ^ 2) 였지만 지금은 O (n)입니다.
소스 (bytesobject.c)에서 :
void
PyBytes_ConcatAndDel(register PyObject **pv, register PyObject *w)
{
PyBytes_Concat(pv, w);
Py_XDECREF(w);
}
/* The following function breaks the notion that strings are immutable:
it changes the size of a string. We get away with this only if there
is only one module referencing the object. You can also think of it
as creating a new string object and destroying the old one, only
more efficiently. In any case, don't use this if the string may
already be known to some other part of the code...
Note that if there's not enough memory to resize the string, the original
string object at *pv is deallocated, *pv is set to NULL, an "out of
memory" exception is set, and -1 is returned. Else (on success) 0 is
returned, and the value in *pv may or may not be the same as on input.
As always, an extra byte is allocated for a trailing \0 byte (newsize
does *not* include that), and a trailing \0 byte is stored.
*/
int
_PyBytes_Resize(PyObject **pv, Py_ssize_t newsize)
{
register PyObject *v;
register PyBytesObject *sv;
v = *pv;
if (!PyBytes_Check(v) || Py_REFCNT(v) != 1 || newsize < 0) {
*pv = 0;
Py_DECREF(v);
PyErr_BadInternalCall();
return -1;
}
/* XXX UNREF/NEWREF interface should be more symmetrical */
_Py_DEC_REFTOTAL;
_Py_ForgetReference(v);
*pv = (PyObject *)
PyObject_REALLOC((char *)v, PyBytesObject_SIZE + newsize);
if (*pv == NULL) {
PyObject_Del(v);
PyErr_NoMemory();
return -1;
}
_Py_NewReference(*pv);
sv = (PyBytesObject *) *pv;
Py_SIZE(sv) = newsize;
sv->ob_sval[newsize] = '\0';
sv->ob_shash = -1; /* invalidate cached hash value */
return 0;
}
경험적으로 검증하는 것은 쉽습니다.
그러나이 최적화는 Python 사양의 일부가 아니라는 점에 유의해야합니다. 중요 내가 아는 한 cPython 구현에만 있습니다. 예를 들어 pypy 또는 jython에 대한 동일한 경험적 테스트는 이전 O (n ** 2) 성능을 보여줄 수 있습니다.
지금까지는 훌륭했지만
아야 2 차보다 훨씬 나빠. 따라서 pypy는 짧은 문자열에서는 잘 작동하지만 큰 문자열에서는 제대로 작동하지 않습니다.
참조 페이지 https://stackoverflow.com/questions/4435169
반응형
'파이썬' 카테고리의 다른 글
파이썬에서 %의 결과는 무엇입니까? (0) | 2020.10.20 |
---|---|
파이썬 Jupyter 노트북 : 위젯이있는 대화 형 플롯 (0) | 2020.10.20 |
파이썬에서 목록 목록의 열에 액세스하는 방법 (0) | 2020.10.19 |
파이썬 conda 용 pip3 설치 (0) | 2020.10.19 |
파이썬 Django Unique Together (외래 키 포함) (0) | 2020.10.19 |
댓글