1
0
Fork 0

changes to benchmark code

This commit is contained in:
Jan Steemann 2012-09-24 08:57:26 +02:00
parent 4181fd5cc4
commit e888894cdb
2 changed files with 181 additions and 17 deletions

View File

@ -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;
};
}
}

View File

@ -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;