Skip to content

Commit b0c45d0

Browse files
committed
OPTIMIZATION #1: Direct PyUnicode_DecodeUTF16 for string conversion (Linux/macOS)
- Eliminates intermediate std::wstring allocation and SQLWCHARToWString conversion - Uses Python C API PyUnicode_DecodeUTF16 directly for UTF-16 encoded SQLWCHAR data - Reduces memory allocations and conversion overhead - Linux/macOS only - Windows uses native wchar_t - Added PERF_TIMER for wstring_conversion measurement
1 parent 9142cdc commit b0c45d0

File tree

1 file changed

+14
-2
lines changed

1 file changed

+14
-2
lines changed

mssql_python/pybind/ddbc_bindings.cpp

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3319,6 +3319,7 @@ SQLRETURN FetchBatchData(SQLHSTMT hStmt, ColumnBuffers& buffers, py::list& colum
33193319
case SQL_WCHAR:
33203320
case SQL_WVARCHAR:
33213321
case SQL_WLONGVARCHAR: {
3322+
PERF_TIMER("construct_rows::wstring_conversion");
33223323
// TODO: variable length data needs special handling, this logic wont suffice
33233324
SQLULEN columnSize = colInfo.columnSize;
33243325
HandleZeroColumnSizeAtFetch(columnSize);
@@ -3329,8 +3330,19 @@ SQLRETURN FetchBatchData(SQLHSTMT hStmt, ColumnBuffers& buffers, py::list& colum
33293330
if (!isLob && numCharsInData < fetchBufferSize) {
33303331
#if defined(__APPLE__) || defined(__linux__)
33313332
SQLWCHAR* wcharData = &buffers.wcharBuffers[col - 1][i * fetchBufferSize];
3332-
std::wstring wstr = SQLWCHARToWString(wcharData, numCharsInData);
3333-
row[col - 1] = wstr;
3333+
// OPTIMIZATION #1: Use PyUnicode_DecodeUTF16 directly instead of intermediate std::wstring
3334+
PyObject* pyStr = PyUnicode_DecodeUTF16(
3335+
reinterpret_cast<const char*>(wcharData),
3336+
numCharsInData * sizeof(SQLWCHAR),
3337+
NULL, // errors - use default handling
3338+
NULL // byteorder - auto-detect
3339+
);
3340+
if (pyStr) {
3341+
row[col - 1] = py::reinterpret_steal<py::object>(pyStr);
3342+
} else {
3343+
PyErr_Clear();
3344+
row[col - 1] = std::wstring(L"");
3345+
}
33343346
#else
33353347
row[col - 1] = std::wstring(
33363348
reinterpret_cast<wchar_t*>(&buffers.wcharBuffers[col - 1][i * fetchBufferSize]),

0 commit comments

Comments
 (0)