mirror of https://gitee.com/bigwinds/arangodb
changes to benchmark code
This commit is contained in:
parent
4181fd5cc4
commit
e888894cdb
|
@ -54,21 +54,58 @@ namespace triagens {
|
||||||
struct BenchmarkRequest {
|
struct BenchmarkRequest {
|
||||||
BenchmarkRequest (const char* url,
|
BenchmarkRequest (const char* url,
|
||||||
map<string, string> params,
|
map<string, string> params,
|
||||||
const char* payload,
|
char* (*genFunc)(),
|
||||||
PB_ArangoMessageContentType contentType,
|
void (*jsonFunc)(PB_ArangoBlobRequest*),
|
||||||
SimpleHttpClient::http_method type) :
|
SimpleHttpClient::http_method type) :
|
||||||
url(url),
|
url(url),
|
||||||
params(params),
|
params(params),
|
||||||
payload(payload),
|
genFunc(genFunc),
|
||||||
contentType(contentType),
|
jsonFunc(jsonFunc),
|
||||||
type(type) {
|
type(type),
|
||||||
|
ptr(0) {
|
||||||
};
|
};
|
||||||
|
|
||||||
|
~BenchmarkRequest () {
|
||||||
|
if (ptr) {
|
||||||
|
TRI_Free(TRI_UNKNOWN_MEM_ZONE, ptr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void createString () {
|
||||||
|
if (genFunc == NULL) {
|
||||||
|
cerr << "invalid call to createString" << endl;
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
ptr = (void*) genFunc();
|
||||||
|
}
|
||||||
|
|
||||||
|
void createString (PB_ArangoBlobRequest* blob) {
|
||||||
|
createString();
|
||||||
|
blob->set_content(getString(), getStringLength());
|
||||||
|
}
|
||||||
|
|
||||||
|
void createJson (PB_ArangoBlobRequest* blob) {
|
||||||
|
if (jsonFunc == NULL) {
|
||||||
|
cerr << "invalid call to createJson" << endl;
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
jsonFunc(blob);
|
||||||
|
}
|
||||||
|
|
||||||
|
char* getString () {
|
||||||
|
return (char*) ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t getStringLength () {
|
||||||
|
return strlen((char*) ptr);
|
||||||
|
}
|
||||||
|
|
||||||
string url;
|
string url;
|
||||||
map<string, string> params;
|
map<string, string> params;
|
||||||
string payload;
|
char* (*genFunc)();
|
||||||
PB_ArangoMessageContentType contentType;
|
void (*jsonFunc)(PB_ArangoBlobRequest*);
|
||||||
SimpleHttpClient::http_method type;
|
SimpleHttpClient::http_method type;
|
||||||
|
void* ptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
|
@ -88,6 +125,7 @@ namespace triagens {
|
||||||
ConditionVariable* condition,
|
ConditionVariable* condition,
|
||||||
const unsigned long batchSize,
|
const unsigned long batchSize,
|
||||||
SharedCounter<unsigned long>* operationsCounter,
|
SharedCounter<unsigned long>* operationsCounter,
|
||||||
|
bool useJson,
|
||||||
Endpoint* endpoint,
|
Endpoint* endpoint,
|
||||||
const string& username,
|
const string& username,
|
||||||
const string& password)
|
const string& password)
|
||||||
|
@ -96,11 +134,13 @@ namespace triagens {
|
||||||
_startCondition(condition),
|
_startCondition(condition),
|
||||||
_batchSize(batchSize),
|
_batchSize(batchSize),
|
||||||
_operationsCounter(operationsCounter),
|
_operationsCounter(operationsCounter),
|
||||||
|
_useJson(useJson),
|
||||||
_endpoint(endpoint),
|
_endpoint(endpoint),
|
||||||
_username(username),
|
_username(username),
|
||||||
_password(password),
|
_password(password),
|
||||||
_client(0),
|
_client(0),
|
||||||
_connection(0) {
|
_connection(0),
|
||||||
|
_time(0.0) {
|
||||||
}
|
}
|
||||||
|
|
||||||
~BenchmarkThread () {
|
~BenchmarkThread () {
|
||||||
|
@ -218,16 +258,23 @@ namespace triagens {
|
||||||
|
|
||||||
blob->set_requesttype(getRequestType(r.type));
|
blob->set_requesttype(getRequestType(r.type));
|
||||||
blob->set_url(r.url);
|
blob->set_url(r.url);
|
||||||
blob->set_contenttype(r.contentType);
|
|
||||||
blob->set_content(r.payload);
|
if (_useJson) {
|
||||||
|
r.createJson(blob);
|
||||||
|
blob->set_contenttype(PB_JSON_CONTENT);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
r.createString(blob);
|
||||||
|
blob->set_contenttype(PB_NO_CONTENT);
|
||||||
|
}
|
||||||
|
|
||||||
for (map<string, string>::const_iterator it = r.params.begin(); it != r.params.end(); ++it) {
|
for (map<string, string>::const_iterator it = r.params.begin(); it != r.params.end(); ++it) {
|
||||||
kv = blob->add_values();
|
kv = blob->add_values();
|
||||||
kv->set_key((*it).first);
|
kv->set_key((*it).first);
|
||||||
kv->set_value((*it).second);
|
kv->set_value((*it).second);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t messageSize = messages.ByteSize();
|
size_t messageSize = messages.ByteSize();
|
||||||
char* message = new char[messageSize];
|
char* message = new char[messageSize];
|
||||||
|
|
||||||
|
@ -246,7 +293,9 @@ namespace triagens {
|
||||||
|
|
||||||
//std::cout << "body length: " << messageSize << ", hash: " << TRI_FnvHashPointer(message, (size_t) messageSize) << "\n";
|
//std::cout << "body length: " << messageSize << ", hash: " << TRI_FnvHashPointer(message, (size_t) messageSize) << "\n";
|
||||||
|
|
||||||
|
Timing timer(Timing::TI_WALLCLOCK);
|
||||||
SimpleHttpResult* result = _client->request(SimpleHttpClient::POST, "/_api/batch", message, (size_t) messageSize, headerFields);
|
SimpleHttpResult* result = _client->request(SimpleHttpClient::POST, "/_api/batch", message, (size_t) messageSize, headerFields);
|
||||||
|
_time += ((double) timer.time()) / 1000000.0;
|
||||||
delete[] message;
|
delete[] message;
|
||||||
|
|
||||||
if (result == 0) {
|
if (result == 0) {
|
||||||
|
@ -296,8 +345,14 @@ namespace triagens {
|
||||||
url.append((*i).second);
|
url.append((*i).second);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
r.createString();
|
||||||
|
|
||||||
map<string, string> headerFields;
|
map<string, string> headerFields;
|
||||||
SimpleHttpResult* result = _client->request(r.type, url, r.payload.c_str(), r.payload.size(), headerFields);
|
Timing timer(Timing::TI_WALLCLOCK);
|
||||||
|
|
||||||
|
SimpleHttpResult* result = _client->request(r.type, url, r.getString(), r.getStringLength(), headerFields);
|
||||||
|
_time += ((double) timer.time()) / 1000000.0;
|
||||||
|
|
||||||
if (result == 0) {
|
if (result == 0) {
|
||||||
_operationsCounter->incFailures();
|
_operationsCounter->incFailures();
|
||||||
return;
|
return;
|
||||||
|
@ -309,6 +364,13 @@ namespace triagens {
|
||||||
delete result;
|
delete result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
double getTime () const {
|
||||||
|
return _time;
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
/// @}
|
/// @}
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -344,6 +406,12 @@ namespace triagens {
|
||||||
|
|
||||||
SharedCounter<unsigned long>* _operationsCounter;
|
SharedCounter<unsigned long>* _operationsCounter;
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief use binary json?
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
bool _useJson;
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
/// @brief endpoint to use
|
/// @brief endpoint to use
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -374,6 +442,12 @@ namespace triagens {
|
||||||
|
|
||||||
triagens::httpclient::GeneralClientConnection* _connection;
|
triagens::httpclient::GeneralClientConnection* _connection;
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief time
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
double _time;
|
||||||
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -87,6 +87,12 @@ static int Operations = 1000;
|
||||||
|
|
||||||
static int BatchSize = 1;
|
static int BatchSize = 1;
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief use binary json?
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
static bool UseJson = false;
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
/// @}
|
/// @}
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -111,6 +117,7 @@ static void ParseProgramOptions (int argc, char* argv[]) {
|
||||||
("concurrency", &Concurrency, "number of parallel connections")
|
("concurrency", &Concurrency, "number of parallel connections")
|
||||||
("requests", &Operations, "total number of operations")
|
("requests", &Operations, "total number of operations")
|
||||||
("batch-size", &BatchSize, "number of operations in one batch")
|
("batch-size", &BatchSize, "number of operations in one batch")
|
||||||
|
("binary-json", &UseJson, "use binary json")
|
||||||
;
|
;
|
||||||
|
|
||||||
BaseClient.setupGeneral(description);
|
BaseClient.setupGeneral(description);
|
||||||
|
@ -136,19 +143,95 @@ static void ParseProgramOptions (int argc, char* argv[]) {
|
||||||
/// @{
|
/// @{
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
char* SEmpty () {
|
||||||
|
return TRI_DuplicateStringZ(TRI_UNKNOWN_MEM_ZONE, "");
|
||||||
|
}
|
||||||
|
|
||||||
|
void JEmpty (PB_ArangoBlobRequest* blob) {
|
||||||
|
}
|
||||||
|
|
||||||
BenchmarkRequest VersionFunc () {
|
BenchmarkRequest VersionFunc () {
|
||||||
map<string, string> params;
|
map<string, string> params;
|
||||||
BenchmarkRequest r("/_api/version", params, "", PB_NO_CONTENT, SimpleHttpClient::GET);
|
BenchmarkRequest r("/_api/version", params, &SEmpty, &JEmpty, SimpleHttpClient::GET);
|
||||||
|
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
BenchmarkRequest InsertFunc () {
|
char* SFunc1 () {
|
||||||
|
return TRI_DuplicateStringZ(TRI_UNKNOWN_MEM_ZONE, "{\"some value\" : 1}");
|
||||||
|
}
|
||||||
|
|
||||||
|
void JFunc1 (PB_ArangoBlobRequest* blob) {
|
||||||
|
PB_ArangoJsonContent* json = blob->mutable_json();
|
||||||
|
json->set_type(PB_REQUEST_TYPE_ARRAY);
|
||||||
|
|
||||||
|
json->mutable_value()->add_objects(); // key
|
||||||
|
json->mutable_value()->add_objects(); // value
|
||||||
|
|
||||||
|
PB_ArangoJsonContent* k = json->mutable_value()->mutable_objects(0);
|
||||||
|
PB_ArangoJsonContent* v = json->mutable_value()->mutable_objects(1);
|
||||||
|
|
||||||
|
k->set_type(PB_REQUEST_TYPE_STRING);
|
||||||
|
k->mutable_value()->set_stringvalue("some value");
|
||||||
|
v->set_type(PB_REQUEST_TYPE_NUMBER);
|
||||||
|
v->mutable_value()->set_numbervalue(1.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
BenchmarkRequest InsertFunc1 () {
|
||||||
map<string, string> params;
|
map<string, string> params;
|
||||||
params["createCollection"] = "true";
|
params["createCollection"] = "true";
|
||||||
params["collection"] = "BenchmarkInsert";
|
params["collection"] = "BenchmarkInsert";
|
||||||
|
|
||||||
BenchmarkRequest r("/_api/document", params, "{\"some value\" : 1}", PB_NO_CONTENT, SimpleHttpClient::POST);
|
BenchmarkRequest r("/_api/document", params, &SFunc1, &JFunc1, SimpleHttpClient::POST);
|
||||||
|
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
char* SFunc2 () {
|
||||||
|
StringBuffer s(TRI_UNKNOWN_MEM_ZONE);
|
||||||
|
|
||||||
|
s.appendChar('{');
|
||||||
|
for (size_t i = 0; i < 1; ++i) {
|
||||||
|
s.appendText("\"some value");
|
||||||
|
s.appendInteger(i);
|
||||||
|
s.appendText("\":");
|
||||||
|
s.appendDecimal((double) i);
|
||||||
|
if (i < 0) {
|
||||||
|
s.appendChar(',');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
s.appendChar('}');
|
||||||
|
|
||||||
|
return TRI_DuplicateStringZ(TRI_UNKNOWN_MEM_ZONE, s.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
void JFunc2 (PB_ArangoBlobRequest* blob) {
|
||||||
|
PB_ArangoJsonContent* json = blob->mutable_json();
|
||||||
|
json->set_type(PB_REQUEST_TYPE_ARRAY);
|
||||||
|
|
||||||
|
for (size_t i = 0; i < 1; ++i) {
|
||||||
|
json->mutable_value()->add_objects(); // key
|
||||||
|
json->mutable_value()->add_objects(); // value
|
||||||
|
|
||||||
|
PB_ArangoJsonContent* k = json->mutable_value()->mutable_objects(i * 2);
|
||||||
|
PB_ArangoJsonContent* v = json->mutable_value()->mutable_objects((i * 2) + 1);
|
||||||
|
|
||||||
|
k->set_type(PB_REQUEST_TYPE_STRING);
|
||||||
|
ostringstream ks;
|
||||||
|
ks << "some value " << i;
|
||||||
|
k->mutable_value()->set_stringvalue(ks.str());
|
||||||
|
v->set_type(PB_REQUEST_TYPE_NUMBER);
|
||||||
|
v->mutable_value()->set_numbervalue((double) i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
BenchmarkRequest InsertFunc2 () {
|
||||||
|
map<string, string> params;
|
||||||
|
params["createCollection"] = "true";
|
||||||
|
params["collection"] = "BenchmarkInsert";
|
||||||
|
|
||||||
|
BenchmarkRequest r("/_api/document", params, &SFunc2, &JFunc2, SimpleHttpClient::POST);
|
||||||
|
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
@ -192,10 +275,11 @@ int main (int argc, char* argv[]) {
|
||||||
Endpoint* endpoint = Endpoint::clientFactory(BaseClient.endpointString());
|
Endpoint* endpoint = Endpoint::clientFactory(BaseClient.endpointString());
|
||||||
endpoints.push_back(endpoint);
|
endpoints.push_back(endpoint);
|
||||||
|
|
||||||
BenchmarkThread* thread = new BenchmarkThread(&InsertFunc,
|
BenchmarkThread* thread = new BenchmarkThread(&InsertFunc2,
|
||||||
&startCondition,
|
&startCondition,
|
||||||
(unsigned long) BatchSize,
|
(unsigned long) BatchSize,
|
||||||
&operationsCounter,
|
&operationsCounter,
|
||||||
|
UseJson,
|
||||||
endpoint,
|
endpoint,
|
||||||
BaseClient.username(),
|
BaseClient.username(),
|
||||||
BaseClient.password());
|
BaseClient.password());
|
||||||
|
@ -225,9 +309,15 @@ int main (int argc, char* argv[]) {
|
||||||
}
|
}
|
||||||
|
|
||||||
double time = ((double) timer.time()) / 1000000.0;
|
double time = ((double) timer.time()) / 1000000.0;
|
||||||
|
double requestTime = 0.0;
|
||||||
|
|
||||||
|
for (int i = 0; i < Concurrency; ++i) {
|
||||||
|
requestTime += threads[i]->getTime();
|
||||||
|
}
|
||||||
|
|
||||||
cout << "Total number of operations: " << Operations << ", batch size: " << BatchSize << ", concurrency level: " << Concurrency << endl;
|
cout << "Total number of operations: " << Operations << ", batch size: " << BatchSize << ", concurrency level: " << Concurrency << endl;
|
||||||
cout << "Total duration: " << fixed << time << " s" << endl;
|
cout << "Total duration: " << fixed << time << " s" << endl;
|
||||||
|
cout << "Total request duration: " << fixed << requestTime << " s" << endl;
|
||||||
cout << "Duration per operation: " << fixed << (time / Operations) << " s" << endl;
|
cout << "Duration per operation: " << fixed << (time / Operations) << " s" << endl;
|
||||||
cout << "Duration per operation per thread: " << fixed << (time / (double) Operations * (double) Concurrency) << " s" << endl << endl;
|
cout << "Duration per operation per thread: " << fixed << (time / (double) Operations * (double) Concurrency) << " s" << endl << endl;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue