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 {
|
||||
BenchmarkRequest (const char* url,
|
||||
map<string, string> params,
|
||||
const char* payload,
|
||||
PB_ArangoMessageContentType contentType,
|
||||
char* (*genFunc)(),
|
||||
void (*jsonFunc)(PB_ArangoBlobRequest*),
|
||||
SimpleHttpClient::http_method type) :
|
||||
url(url),
|
||||
params(params),
|
||||
payload(payload),
|
||||
contentType(contentType),
|
||||
type(type) {
|
||||
genFunc(genFunc),
|
||||
jsonFunc(jsonFunc),
|
||||
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;
|
||||
map<string, string> params;
|
||||
string payload;
|
||||
PB_ArangoMessageContentType contentType;
|
||||
char* (*genFunc)();
|
||||
void (*jsonFunc)(PB_ArangoBlobRequest*);
|
||||
SimpleHttpClient::http_method type;
|
||||
void* ptr;
|
||||
};
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
@ -88,6 +125,7 @@ namespace triagens {
|
|||
ConditionVariable* condition,
|
||||
const unsigned long batchSize,
|
||||
SharedCounter<unsigned long>* operationsCounter,
|
||||
bool useJson,
|
||||
Endpoint* endpoint,
|
||||
const string& username,
|
||||
const string& password)
|
||||
|
@ -96,11 +134,13 @@ namespace triagens {
|
|||
_startCondition(condition),
|
||||
_batchSize(batchSize),
|
||||
_operationsCounter(operationsCounter),
|
||||
_useJson(useJson),
|
||||
_endpoint(endpoint),
|
||||
_username(username),
|
||||
_password(password),
|
||||
_client(0),
|
||||
_connection(0) {
|
||||
_connection(0),
|
||||
_time(0.0) {
|
||||
}
|
||||
|
||||
~BenchmarkThread () {
|
||||
|
@ -218,16 +258,23 @@ namespace triagens {
|
|||
|
||||
blob->set_requesttype(getRequestType(r.type));
|
||||
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) {
|
||||
kv = blob->add_values();
|
||||
kv->set_key((*it).first);
|
||||
kv->set_value((*it).second);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
size_t messageSize = messages.ByteSize();
|
||||
char* message = new char[messageSize];
|
||||
|
||||
|
@ -246,7 +293,9 @@ namespace triagens {
|
|||
|
||||
//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);
|
||||
_time += ((double) timer.time()) / 1000000.0;
|
||||
delete[] message;
|
||||
|
||||
if (result == 0) {
|
||||
|
@ -296,8 +345,14 @@ namespace triagens {
|
|||
url.append((*i).second);
|
||||
}
|
||||
|
||||
r.createString();
|
||||
|
||||
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) {
|
||||
_operationsCounter->incFailures();
|
||||
return;
|
||||
|
@ -309,6 +364,13 @@ namespace triagens {
|
|||
delete result;
|
||||
}
|
||||
|
||||
|
||||
public:
|
||||
|
||||
double getTime () const {
|
||||
return _time;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @}
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -344,6 +406,12 @@ namespace triagens {
|
|||
|
||||
SharedCounter<unsigned long>* _operationsCounter;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief use binary json?
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
bool _useJson;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief endpoint to use
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -374,6 +442,12 @@ namespace triagens {
|
|||
|
||||
triagens::httpclient::GeneralClientConnection* _connection;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief time
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
double _time;
|
||||
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
@ -87,6 +87,12 @@ static int Operations = 1000;
|
|||
|
||||
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")
|
||||
("requests", &Operations, "total number of operations")
|
||||
("batch-size", &BatchSize, "number of operations in one batch")
|
||||
("binary-json", &UseJson, "use binary json")
|
||||
;
|
||||
|
||||
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 () {
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
params["createCollection"] = "true";
|
||||
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;
|
||||
}
|
||||
|
@ -192,10 +275,11 @@ int main (int argc, char* argv[]) {
|
|||
Endpoint* endpoint = Endpoint::clientFactory(BaseClient.endpointString());
|
||||
endpoints.push_back(endpoint);
|
||||
|
||||
BenchmarkThread* thread = new BenchmarkThread(&InsertFunc,
|
||||
BenchmarkThread* thread = new BenchmarkThread(&InsertFunc2,
|
||||
&startCondition,
|
||||
(unsigned long) BatchSize,
|
||||
&operationsCounter,
|
||||
UseJson,
|
||||
endpoint,
|
||||
BaseClient.username(),
|
||||
BaseClient.password());
|
||||
|
@ -225,9 +309,15 @@ int main (int argc, char* argv[]) {
|
|||
}
|
||||
|
||||
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 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 per thread: " << fixed << (time / (double) Operations * (double) Concurrency) << " s" << endl << endl;
|
||||
|
||||
|
|
Loading…
Reference in New Issue