2011-10-25 4 views
1

나는 asp 페이지에서 C++ 코드에 액세스하고 xml 문자열을 돌려받습니다. 웹 페이지에 액세스 할 때마다 웹 브라우저에서 시간 초과가 발생합니다.루프가 매우 느려서 asp가 시간 초과 됨

문제를 알고 있지만 문제를 해결하는 방법을 모르겠다 고 생각합니다. 나는 XML 문자열이 얼마나 커질 지 확신하지 못하기 때문에 변수를 선언 할 때 어떤 크기로 선언해야 할지를 모르므로 iDataBufferSize를 가장 큰 것으로 선언 할 수있다.

다음 함수에는 forp 코드로 돌아 오는 xml 문자열을 만드는 for 루프가 있습니다.

for 루프는 약 500 개의 행을 통과해야하며이 줄을 wcscat_s (wDataBuffer, iSize, wBuffer)라고 치면 디스크 스왑이 시작되고 for 루프가 느려집니다.

iDataBufferSize를 작게 만들면 작동하지만, XML 문자열에 버퍼를 충분히 만들지는 않을 것이라는 것을 알고 있습니다.

감사 -Dimitry

LPWCH wLargeDataBuffer = 0; 
char *cLargeCBuffer = 0; 
size_t iDataBufferSize = 93276800; 

wLargeDataBuffer = new WCHAR[iDataBufferSize]; 
cLargeCBuffer = new char[iDataBufferSize]; 

memset(wLargeDataBuffer, 0, iDataBufferSize); 
memset(cLargeCBuffer, 0, iDataBufferSize); 

iDataLen = getCServPBJList(wLargeDataBuffer, iDataBufferSize); 

int CAdminConsoleInterface::getCServPBJList(LPWCH wDataBuffer, size_t iSize) { 
    wcscpy_s(wDataBuffer, iSize, L"<jobsList>"); 
    houseKeeper->getCServJobsXML(wDataBuffer, iSize, configHandler->getTextValue (L"UniqueID"), L'P'); 
    wcscat_s(wDataBuffer, iSize, L"</jobsList>"); 
    return wcslen(wDataBuffer); 
    } 

int CHouseKeeper::getCServJobsXML(LPWCH wDataBuffer, size_t iSize, LPWCH wLocation, WCHAR wPrefix) { 
    WCHAR wIndexPath[1024]; 
    WCHAR wBuffer[1024]; 
    LPWCH wTempBuffer = new WCHAR[16384]; 
    int rc; 
    char *zErrMsg=0; 
    char **results; 
    int nrow=0, ncol=0; 
    char cSQLDB[1024]; 
    sqlite3 *CServDB; 
    size_t convertedChars=0; 
    size_t origsize; 

    cout << "Looking up CServ jobs." << endl; 
    getIndexPath(wIndexPath, 1024); 
    wcscat_s(wIndexPath, 1024, L"CServ.db"); 
    WideCharToMultiByte(CP_UTF8, 0, wIndexPath, -1, cSQLDB, PATH_LENGTH, 0,0); 

    //cout << "Opening DB: " << cSQLDB << endl; 
    rc = sqlite3_open(cSQLDB, &CServDB); 
    if (rc != SQLITE_OK) 
    { 
     cout << "Error opening DB." << endl; 
     return -1; 
    } 
    rc = sqlite3_get_table(CServDB, "SELECT * FROM OServ_jobs;", &results, &nrow, &ncol, &zErrMsg); 

    //cout << "nrow: " << nrow << " - ncol: " << ncol << endl; 
    for (int i=1; i<=nrow; i++) { 
     origsize = strlen(results[1+(ncol*i)]) + 1; 
     mbstowcs_s(&convertedChars, wBuffer, origsize, results[1+(ncol*i)], 1024); 
     wcscat_s(wDataBuffer, iSize, L"<job id=\""); 
     wcscat_s(wDataBuffer, iSize, CHelper::escapeXMLData(wBuffer, wTempBuffer, 16384)); 
     wcscat_s(wDataBuffer, iSize, L"\" type=\""); 
     //wcout << "JobID: " << wBuffer << endl; 
     origsize = strlen(results[4+(ncol*i)]) + 1; 
     mbstowcs_s(&convertedChars, wBuffer, origsize, results[4+(ncol*i)], 1024); 
     wcscat_s(wDataBuffer, iSize, wBuffer); 
     //wcout << "Type: " << wBuffer << endl; 
     wcscat_s(wDataBuffer, iSize, L"\">"); 

     origsize = strlen(results[(ncol*i)]) + 1; 
     mbstowcs_s(&convertedChars, wBuffer, origsize, results[(ncol*i)], 1024); 
     wcscat_s(wDataBuffer, iSize, L"<currentLocation>"); 
     wcscat_s(wDataBuffer, iSize, wBuffer); 
     //wcout << "Location: " << wBuffer << endl; 
     wcscat_s(wDataBuffer, iSize, L"</currentLocation>"); 

     wcscat_s(wDataBuffer, iSize, L"<date>"); 
     origsize = strlen(results[2+(ncol*i)]) + 1; 
     mbstowcs_s(&convertedChars, wBuffer, origsize, results[2+(ncol*i)], 1024); 
     wcscat_s(wDataBuffer, iSize, wBuffer); 
     //wcout << "Date: " << wBuffer << endl; 
     wcscat_s(wDataBuffer, iSize, L"</date>"); 

     wcscat_s(wDataBuffer, iSize, L"<time>"); 
     origsize = strlen(results[3+(ncol*i)]) + 1; 
     mbstowcs_s(&convertedChars, wBuffer, origsize, results[3+(ncol*i)], 1024); 
     wcscat_s(wDataBuffer, iSize, wBuffer); 
     //wcout << "Time: " << wBuffer << endl; 
     wcscat_s(wDataBuffer, iSize, L"</time>"); 

     wcscat_s(wDataBuffer, iSize, L"</job>"); 

     memset(wBuffer, 0, 1024); 
     memset(wTempBuffer, 0, 16384); 
    } 

    //wcout << "Data: " << wDataBuffer << endl; 
    delete []wTempBuffer; 
    sqlite3_free_table(results); 
    sqlite3_close(CServDB); 
    return wcslen(wDataBuffer); 
} 
+1

'std :: string' 또는'std :: vector'를 사용하십시오. 결코 물건을 지우지 마라. – GManNickG

답변

8

도로 아래로 선을 그리는 사람에 대한 오래된 비유가있다. 처음 1 시간, 그는 500 피트를 칠했다. 다음 시간에는 300 피트 밖에 칠하지 못했습니다. 다음 시간, 단 100 피트. 그의 상사는 왜 그가 너무 느린 지 묻습니다. 그리고 페인트 통이 1,000 피트 떨어져있을 때 칠하기가 몹시 어렵다고 설명합니다.

각 연결 호출에 줄의 시작 부분에 대한 포인터를 전달합니다. 그런 다음 끝까지 찾기 위해 줄을서야합니다. 그러면 조금 더 커지게됩니다. 아야.

큰 문자열에 너무 많은 연결 호출을해서는 안됩니다. 가장 간단한 수정 - 중간 버퍼를 사용하십시오. 'for'루프를 반복 할 때마다 중간 버퍼로 연결하십시오. 그런 다음 하나의 호출을 사용하여 해당 중간 버퍼를 주 버퍼에 추가합니다. 이상적으로, 중간 버퍼를 주 버퍼에 추가하는 호출에서, 포인터를 시작 부분이 아닌 버퍼에 더 전달하십시오.

실제로 최상의 솔루션은 효율적인 연결 작업이있는 문자열 클래스를 사용하는 것입니다.

+1

아마도 아기 사탕처럼 문자열 흐름이 유용 할 수도 있습니다. –

+0

중간 버퍼는 어떤 크기로 만들까요? 중간 버퍼로 같은 문제가 발생하지 않을까요? – ZystemsGo

+0

이상적으로, 가장 큰 행보다 클 수 있습니다. 필요하다면 필요한 크기를 과대 평가하고 필요할 경우 다시 할당 할 수있는 수학을 할 수 있습니다. 네, 같은 문제를 만들지 만, 여러 번, 여러 번 덜 만듭니다. 행당 15 회가 아니라 행당 한 번만 문제가되는 커다란 버퍼에 연결됩니다. –

관련 문제