Below a small "demo" file that is used to measure execution time. I want to update a sequence with nextvval 100K times.
CREATE SEQUENCE "TEST_SEQ"
MINVALUE 1
MAXVALUE 10000000000
INCREMENT BY 1
START WITH 1
CACHE 200
NOORDER
CYCLE;
declare local_1 INT;
BEGIN
FOR i IN 1..100000 LOOP
select TEST_SEQ.nextval into local_1 from dual;
END LOOP;
END;
/
it takes less than 2 seconds for the counter to reach 100K.
However the following code wants more than 7 seconds to reach 10K (an order of magnitude less).
I am wondering if there is something better I can do, or if I miss something. Is it possible using the library to reach better number, ie 2K-3K per second?
I used a simple thread pool from boost.
#include <boost/array.hpp>
#include <iostream>
#include <boost/asio/io_service.hpp>
#include <boost/bind.hpp>
#include <boost/thread/thread.hpp>
#include <boost/chrono/thread_clock.hpp>
#include <memory>
#include <chrono>
dpiContext *context;
dpiPool *pool;
int ShowError(dpiContext *context)
{
return 1;
}
int icalc(int x) {
dpiConn *conn;
dpiStmt *stmt;
uint32_t numQueryColumns;
const char *sql = "select TEST_SEQ.nextval from dual";
if (dpiPool_acquireConnection(pool, NULL, 0, NULL, 0, NULL, &conn) < 0 )
return ShowError(context);
if (dpiConn_prepareStmt(conn, 0, sql, strlen(sql), NULL, 0, &stmt) < 0)
return ShowError(context);
if ( dpiStmt_execute(stmt, DPI_MODE_EXEC_DEFAULT, &numQueryColumns) < 0)
return ShowError(context);
if ( dpiStmt_release(stmt) < 0 )
return ShowError(context);
if( conn ) {
dpiConn_release(conn) ;
return 0; //"Hello world";
} else {
return 1; //"err";
}
}
int main(int argc, char** argv)
{
dpiErrorInfo errorInfo;
//dpiContext *context;
if (dpiContext_create(DPI_MAJOR_VERSION, DPI_MINOR_VERSION, &context, &errorInfo) < 0) {
return -1;
}
dpiCommonCreateParams commonParams;
dpiPoolCreateParams createParams;
//dpiPool *pool;
if (dpiContext_initCommonCreateParams(context, &commonParams) < 0) {
std::cout << "cannot init common params" << std::endl;
return 1;
}
commonParams.createMode = DPI_MODE_CREATE_THREADED;
if (dpiContext_initPoolCreateParams(context, &createParams) < 0)
{
std::cout << "cannot init the params" << std::endl;
return 1; //dpiTestCase_setFailedFromError(testCase);
}
createParams.minSessions = 15; //MINSESSIONS;
createParams.maxSessions = 20; //MAXSESSIONS;
createParams.sessionIncrement = 1; //SESSINCREMENT;
if (dpiPool_create(context, "DB", strlen("DB"),
"DB", strlen("DB"), "1.7.7.1:1521/DEV",
strlen("10.70.7.146:1521/L10DEV"), &commonParams, &createParams, &pool) < 0)
return 1;
if (dpiPool_setGetMode(pool, DPI_MODE_POOL_GET_WAIT) < 0)
return 1;
int maxthreads = 50;
boost::asio::io_service ioService;
std::unique_ptr<boost::asio::io_service::work> work( new boost::asio::io_service::work(ioService));
boost::thread_group threadpool; //pool
std::cout << "thread starts with max threads: : " << maxthreads << std::endl;
for (std::size_t i = 0; i < maxthreads; ++i)
threadpool.create_thread(boost::bind(&boost::asio::io_service::run, &ioService));
using namespace boost::chrono;
//thread_clock::time_point start = thread_clock::now();
std::chrono::steady_clock::time_point begin = std::chrono::steady_clock::now();
for(int i = 0 ; i < 10000; i++)
ioService.post(boost::bind(icalc, 42));
work.reset();
threadpool.join_all();
ioService.stop();
std::chrono::steady_clock::time_point end= std::chrono::steady_clock::now();
std::cout << "Time difference = " << std::chrono::duration_cast<std::chrono::seconds>(end - begin).count() <<std::endl;
return 0;
}
It is a little bit critical for us, since we want to decide if we will use oracle for a high performance server.
Thank you very much in advance.