Java — JDBC значительно быстрее, чем OCCI. Должен ли я быть удивлен?

Я очень удивлен тестом производительности, сравнивающим OCCI (Oracle C ++ Call Interface) и старый JDBC.

Вот код:

#include <iostream>
#include <cstdlib>
#include <occi.h>

using namespace oracle::occi;
using namespace std;

const string username   = "system";
const string password   = "******";
const string url        = "(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)(HOST=localhost)(PORT=1521)))(CONNECT_DATA=(SERVER=DEDICATED)(SERVICE_NAME=XE)))";
const string sql        = "select * from CREDITO.movtos_cuentas";

int main(int argc, char** argv) {

cout << "Oracle Connectivity" << endl;

Environment *env = Environment::createEnvironment(Environment::DEFAULT);
Connection *conn = env->createConnection(username, password, url);
Statement *stm = conn->createStatement(sql);
ResultSet *rs = stm->executeQuery();

unsigned long count = 0;

while (rs->next()) {
count++;
}

stm->closeResultSet(rs);
conn->terminateStatement(stm);
env->terminateConnection(conn);
Environment::terminateEnvironment(env);

cout << "Registros na CREDITO.MOVTOS_CUENTAS: " << count << endl;

return 0;
}

А вот код Java:

package oraconnect.jdbc;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

public class OraconnectJdbc {

public static void main(String[] args) {
Connection conn = null;
Statement stm = null;
ResultSet rs = null;

try {
Class.forName("oracle.jdbc.driver.OracleDriver");
conn = DriverManager.getConnection(
"jdbc:oracle:thin:@127.0.0.1:1521:xe", "system", "******");
stm = conn.createStatement();
rs = stm.executeQuery("select * from CREDITO.movtos_cuentas");
long count = 0;
while (rs.next()) {
count++;
}

System.out.printf("Registros na CREDITO.MOVTOS_CUENTAS: %d\n", count);
} catch (Exception e) {
e.printStackTrace();
} finally {
if (rs != null) {
try {
rs.close();
} catch (SQLException e) {
//Ignore
}
}
if (stm != null) {
try {
stm.close();
} catch (SQLException e) {
//Ignore
}
}
if (conn != null) {
try {
conn.close();
} catch (SQLException e) {
//Ignore
}
}
}
}
}

Исполнение:

Версия C ++

time LD_LIBRARY_PATH=/home/eduardo/Private/Oracle/instantclient_11_2/. ./oraconnect

Версия Java

time java -jar oraconnect-jdbc.jar -cp lib/oracle-driver-11.2.0.3.jar

C ++ Результат:

real    1m29.392s
user    0m32.788s
sys     0m20.812s

Результат Java:

real    0m28.404s
user    0m12.076s
sys     0m4.236s

Заключение:

Java была значительно быстрее, чем C ++

Интересно, допустил ли я ошибку или использовал плохую практику с версией C ++. Кто-нибудь может помочь мне понять этот результат?

-4

Решение

Как вы измерили время, различия действительны.
Если вы хотите понять, почему они разные, вам нужно разделить все время на несколько частей и посмотреть, похожи они или нет. и понять причину разницы.
Это может быть сделано многими различными методами, такими как отслеживание или выборка стеков вызовов в ваших двоичных файлах, выполнение tcpdump на сетевом уровне или многие другие.
Очень удобный метод — включить SQL_TRACE в базе данных Oracle — там вы получите много информации о том, где тратится время. Хорошее введение в методы для включения SQL_TRACE: https://oracle-base.com/articles/misc/sql-trace-10046-trcsess-and-tkprof.
Эти файлы трассировки содержат много данных и их трудно читать, особенно в начале. Для обработки этих файлов доступно несколько инструментов (большинство из них называются «Профилировщик»). Ведущий продукт (с моей точки зрения) Method-R Profiler — но так как это стоит денег, вы можете попробовать https://antognini.ch/2017/03/tvdxtat-4-0-beta-11/ вместо.

Без дополнительной информации никто не может сказать, в чем причина различий в производительности. Но с помощью доступных инструментов вы можете их идентифицировать. тогда вы либо принимаете одно решение быстрее другого, либо исправляете его.

Редактировать:
Я приведу пример:
Помимо многих других причин, есть поведение по умолчанию:
OCCI выбирает 2 строки одновременно:
Доступ к базе данных Oracle с использованием C ++

По умолчанию предварительная выборка включена, и база данных извлекает дополнительную
грести все время.

Но у jdbc есть набор результатов 10:
Руководство разработчика базы данных JDBC — набор результатов

По умолчанию, когда Oracle JDBC выполняет запрос, он получает набор результатов.
10 строк за раз от курсора базы данных.

Так что может случиться так, что у вас в 5 раз больше сетевых обращений с OCCI, чем с jdbc.

Это только пример — это может быть причиной вашего наблюдения или нет. Чтобы быть уверенным, вам нужно измерить, а не угадать или попросить угадать.

0

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]