Bibliothèque OTL - SQL Server - C ++ - Performance
-
21-12-2019 - |
Question
J'ai récemment commencé à tester la bibliothèque
Les deux applications effectuent les tâches suivantes: Ouvrez la connexion DB Créer (et réserver espace) pour l'objet conteneur. Exécuter la commande de sélection de l'instruction. Pour chaque enregistrement récupéré de dB Créer une entité à l'aide de l'objet dB (flux / lecteur) Ajoutez l'objet au conteneur Fermer
.NET C # App nécessite 0,5 seconde pour compléter cette tâche, tandis que l'application OTL-C ++ prend 0,7 seconde à compléter et je me demande
Snippet de C ++ Code:
#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;
}
La solution
Je ne le pense pas, lorsque vous regardez la source de code d'OTL, il utilise ODBC API pour SQL Server et est uniquement optimisé en tant que couche supérieure ODBC.Le SQL Server .NET 4.0 utilisera l'API pilote SQL au lieu d'API ODBC pour la raison de la performance.
De plus, si vous ne prélevez pas votre consommation de mémoire, vous vous perdez toujours à .NET et Java en raison de l'appel de la fonction SysallocMem.C'est comme essayer de mesurer 4000 appel à Sysalloc vs 1 appel à Sysalloc.Votre problème de performance est directement lié à ces fonctions.