Pergunta

Recentemente comecei a testar o Biblioteca OTL com o servidor SQL usando o Visual Studio 2013.Meus testes demonstraram que o desempenho de instruções select simples em uma tabela de contagem de 10.000 é 40% mais lento do que o desempenho de uma tabela de contagem de 10.000. semelhante .NET 4.0 aplicação de teste.Todos os testes foram realizados com todas as otimizações ativadas para ambas as plataformas.

Ambos os aplicativos executam as seguintes tarefas:Abra a conexão DB Criar (e reservar espaço) para o objeto de contêiner.Execute o comando de instrução select.Para cada registro buscada do banco

O aplicativo .NET C# requer 0,5 segundos para concluir esta tarefa, enquanto o aplicativo OTL-C++ leva 0,7 segundos para ser concluído e eu me pergunto se for possível otimizar o aplicativo C++ para um desempenho mais rápido?

Trecho de código C++:

#define OTL_ODBC_MSSQL_2008     // Compile OTL 4/ODBC, MS SQL 2008
#define OTL_CPP_11_ON
#define OTL_STL                 // Turn on STL features
#define OTL_ANSI_CPP            // Turn on ANSI C++ typecasts
#define OTL_UNICODE             // Enable Unicode OTL for ODBC
#include "otlv4.h"    
 class Employee

{
private:
    int employeeId;
    wstring regno;
    wstring name;
    wstring surname;

public:
    Employee()
    {
    }

    Employee(otl_stream& stream)
    {
        unsigned short _regno[32];
        unsigned short _name[32];
        unsigned short _surname[32];

        if (!stream.is_null())
        {
            stream >> employeeId;
        }

        if (!stream.is_null())
        {
            stream >> (unsigned char*)_regno;
            regno = (wchar_t*)_regno;
        }

        if (!stream.is_null()){
            stream >> (unsigned char*)_name;
            name = (wchar_t*)_name;
        }


        if (!stream.is_null()){
            stream >> (unsigned char*)_surname;
            surname = (wchar_t*)_surname;
        }
    }

    int GetEmployeeId() const
    {
        return employeeId;
    }
};



otl_connect db;
int main()
{
    otl_connect::otl_initialize();
    try
    {
otl_connect::otl_initialize();
    try
    {
        // connect
        db.rlogon("DSN=SQLODBC");

        // start timing
        clock_t begin = clock();
        otl_stream i(10000, "SELECT Id, Field1, Field2, Field3 FROM Test", db);

        // create container
        vector<Employee> employeeList;
        employeeList.reserve(10000);

        // iterate and fill container
        while (!i.eof())
        {
            Employee employee(i);
            employeeList.push_back(employee);
        }
        i.close();

        // cleanup
        size_t size = employeeList.size();  
        clock_t end = clock();
        double elapsed_secs = double(end - begin) / CLOCKS_PER_SEC;
        cout << "Total records:" << size << endl;
        cout << "Time elapsed to read all records:" << elapsed_secs << endl;



    }

    catch (otl_exception& p){ // intercept OTL exceptions
        cerr << p.msg << endl; // print out error message
        cerr << p.stm_text << endl; // print out SQL that caused the error
        cerr << p.sqlstate << endl; // print out SQLSTATE message
        cerr << p.var_info << endl; // print out the variable that caused the error
    }

    db.logoff();
return EXIT_SUCCESS;
}
Foi útil?

Solução

Acho que não, quando você olha o código-fonte do otl, ele usa a API ODBC para SQL Server e é otimizado apenas como uma camada superior do odbc.O SQL Server .NET 4.0 usará a API do driver SQL em vez da API ODBC por motivos de desempenho.

Além disso, se você não pré-alocar o consumo de memória, sempre perderá para .NET e Java devido à chamada de função SysAllocMem.É como tentar medir 4.000 chamadas para SysAlloc versus 1 chamada para SysAlloc.Seu problema de desempenho está diretamente ligado a essas funções.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top