parent
82be433d41
commit
56913be6bb
14 changed files with 26 additions and 500 deletions
@ -1,35 +0,0 @@ |
||||
|
||||
import sys |
||||
|
||||
benchmarks = {} |
||||
color_map = {'proto2_compiled': 'FF0000', |
||||
'proto2_table': 'FF00FF', |
||||
'upb_table_byref': '0000FF', |
||||
'upb_table_byval': '00FF00'} |
||||
for line in sys.stdin: |
||||
name, val = line.split(': ') |
||||
components = name.split('_') |
||||
benchmark = '_'.join(components[1:3]) |
||||
variant = '_'.join(components[3:]) |
||||
if benchmark not in benchmarks: |
||||
benchmarks[benchmark] = [] |
||||
benchmarks[benchmark].append((variant, int(val))) |
||||
|
||||
def encode(x): |
||||
digits = (range(ord("A"), ord("Z")+1) + range(ord("a"), ord("z")+1) + |
||||
range(ord("0"), ord("9")+1) + [ord("."), ord("-")]) |
||||
return chr(digits[x / 64]) + chr(digits[x % 64]) |
||||
|
||||
for benchmark, values in benchmarks.items(): |
||||
def cmp(a, b): |
||||
return b[1] - a[1] |
||||
values.sort(cmp) |
||||
variants = [x[0] for x in values] |
||||
values = [x[1] for x in values] |
||||
scaling = 400 |
||||
encoded_values = [encode((x * 4096 / scaling) - 1) for x in values] |
||||
legend = "chdl=%s" % ("|".join(variants)) |
||||
colors = "chco=%s" % ("|".join([color_map[x] for x in variants])) |
||||
data = "chd=e:%s" % ("".join(encoded_values)) |
||||
url = "http://chart.apis.google.com/chart?cht=bhs&chs=500x200&chtt=%s+(MB/s)&chxt=x&chxr=0,0,%d&%s" % (benchmark, scaling, "&".join([legend, data, colors])) |
||||
print url |
@ -1,55 +0,0 @@ |
||||
|
||||
#include <stdbool.h> |
||||
#include <time.h> |
||||
#include <stdio.h> |
||||
#include <unistd.h> |
||||
#include <string.h> |
||||
|
||||
/* Cycle between a bunch of different messages, to avoid performance
|
||||
* variations due to memory effects of a particular allocation pattern. */ |
||||
#ifndef NUM_MESSAGES |
||||
#define NUM_MESSAGES 32 |
||||
#endif |
||||
|
||||
static bool initialize(); |
||||
static void cleanup(); |
||||
static size_t run(int i); |
||||
|
||||
int main (int argc, char *argv[]) |
||||
{ |
||||
(void)argc; |
||||
|
||||
/* Change cwd to where the binary is. */ |
||||
char *lastslash = strrchr(argv[0], '/'); |
||||
char *progname = argv[0]; |
||||
if(lastslash) { |
||||
*lastslash = '\0'; |
||||
if(chdir(argv[0]) < 0) { |
||||
fprintf(stderr, "Error changing directory to %s.\n", argv[0]); |
||||
return 1; |
||||
} |
||||
*lastslash = '/'; |
||||
progname = lastslash + 3; /* "/b_" */ |
||||
} |
||||
|
||||
if(!initialize()) { |
||||
fprintf(stderr, "%s: failed to initialize\n", argv[0]); |
||||
return 1; |
||||
} |
||||
|
||||
size_t total_bytes = 0; |
||||
clock_t before = clock(); |
||||
for(int i = 0; true; i++) { |
||||
if((i & 0xFF) == 0 && (clock() - before > CLOCKS_PER_SEC)) break; |
||||
size_t bytes = run(i); |
||||
if(bytes == 0) { |
||||
fprintf(stderr, "%s: failed.\n", argv[0]); |
||||
return 2; |
||||
} |
||||
total_bytes += bytes; |
||||
} |
||||
double elapsed = ((double)clock() - before) / CLOCKS_PER_SEC; |
||||
printf("%s:%d\n", progname, (int)(total_bytes / elapsed / (1 << 20))); |
||||
cleanup(); |
||||
return 0; |
||||
} |
@ -1,94 +0,0 @@ |
||||
|
||||
#include "main.c" |
||||
|
||||
#include <stdlib.h> |
||||
#include "upb/bytestream.h" |
||||
#include "upb/def.h" |
||||
#include "upb/pb/decoder.h" |
||||
#include "upb/pb/glue.h" |
||||
|
||||
static char *input_str; |
||||
static size_t input_len; |
||||
static const upb_msgdef *def; |
||||
upb_pipeline pipeline; |
||||
static upb_sink *sink; |
||||
|
||||
static void *startsubmsg(void *closure, const void *hd) { |
||||
UPB_UNUSED(closure); |
||||
UPB_UNUSED(hd); |
||||
return input_str; |
||||
} |
||||
|
||||
void onmreg(void *c, upb_handlers *h) { |
||||
UPB_UNUSED(c); |
||||
upb_msg_iter i; |
||||
upb_msg_begin(&i, upb_handlers_msgdef(h)); |
||||
for(; !upb_msg_done(&i); upb_msg_next(&i)) { |
||||
const upb_fielddef *f = upb_msg_iter_field(&i); |
||||
if (upb_fielddef_type(f) == UPB_TYPE_MESSAGE) { |
||||
upb_handlers_setstartsubmsg(h, f, startsubmsg, NULL, NULL); |
||||
} |
||||
} |
||||
} |
||||
|
||||
static bool initialize() |
||||
{ |
||||
// Initialize upb state, decode descriptor.
|
||||
upb_status status = UPB_STATUS_INIT; |
||||
upb_symtab *s = upb_symtab_new(&s); |
||||
upb_load_descriptor_file_into_symtab(s, MESSAGE_DESCRIPTOR_FILE, &status); |
||||
if(!upb_ok(&status)) { |
||||
fprintf(stderr, "Error reading descriptor: %s\n", |
||||
upb_status_getstr(&status)); |
||||
return false; |
||||
} |
||||
|
||||
def = upb_dyncast_msgdef(upb_symtab_lookup(s, MESSAGE_NAME, &def)); |
||||
if(!def) { |
||||
fprintf(stderr, "Error finding symbol '%s'.\n", MESSAGE_NAME); |
||||
return false; |
||||
} |
||||
upb_symtab_unref(s, &s); |
||||
|
||||
// Read the message data itself.
|
||||
input_str = upb_readfile(MESSAGE_FILE, &input_len); |
||||
if(input_str == NULL) { |
||||
fprintf(stderr, "Error reading " MESSAGE_FILE "\n"); |
||||
return false; |
||||
} |
||||
|
||||
// Cause all messages to be read, but do nothing when they are.
|
||||
const upb_handlers* handlers = |
||||
upb_handlers_newfrozen(def, NULL, &handlers, &onmreg, NULL); |
||||
const upb_handlers* decoder_handlers = |
||||
upb_pbdecoder_gethandlers(handlers, JIT, &decoder_handlers); |
||||
upb_msgdef_unref(def, &def); |
||||
|
||||
upb_pipeline_init(&pipeline, NULL, 0, upb_realloc, NULL); |
||||
upb_sink *s2 = upb_pipeline_newsink(&pipeline, handlers); |
||||
sink = upb_pipeline_newsink(&pipeline, decoder_handlers); |
||||
upb_pipeline_donateref(&pipeline, decoder_handlers, &decoder_handlers); |
||||
upb_pipeline_donateref(&pipeline, handlers, &handlers); |
||||
upb_pbdecoder *decoder = upb_sink_getobj(sink); |
||||
upb_pbdecoder_resetsink(decoder, s2); |
||||
return true; |
||||
} |
||||
|
||||
static void cleanup() |
||||
{ |
||||
free(input_str); |
||||
upb_pipeline_uninit(&pipeline); |
||||
} |
||||
|
||||
static size_t run(int i) |
||||
{ |
||||
(void)i; |
||||
upb_pipeline_reset(&pipeline); |
||||
if (!upb_bytestream_putstr(sink, input_str, input_len)) { |
||||
fprintf(stderr, "Decode error: %s", |
||||
upb_status_getstr(upb_pipeline_status(&pipeline))); |
||||
return 0; |
||||
} |
||||
return input_len; |
||||
|
||||
} |
@ -1,57 +0,0 @@ |
||||
// Tests speed of upb parsing into proto2 generated classes.
|
||||
|
||||
#define __STDC_LIMIT_MACROS 1 |
||||
#include "main.c" |
||||
|
||||
#include <stdint.h> |
||||
#include "upb/bytestream.h" |
||||
#include "upb/def.h" |
||||
#include "upb/pb/decoder.h" |
||||
#include "upb/pb/glue.h" |
||||
#include "upb/bindings/google/bridge.h" |
||||
#include MESSAGE_HFILE |
||||
|
||||
const char *str; |
||||
size_t len; |
||||
MESSAGE_CIDENT msg[NUM_MESSAGES]; |
||||
upb::SeededPipeline<8192> pipeline(upb_realloc, NULL); |
||||
upb::Sink *decoder_sink; |
||||
upb::Sink *proto2_sink; |
||||
|
||||
static bool initialize() |
||||
{ |
||||
// Read the message data itself.
|
||||
str = upb_readfile(MESSAGE_FILE, &len); |
||||
if(str == NULL) { |
||||
fprintf(stderr, "Error reading " MESSAGE_FILE "\n"); |
||||
return false; |
||||
} |
||||
|
||||
const upb::Handlers* h = upb::google::NewWriteHandlers(MESSAGE_CIDENT(), &h); |
||||
const upb::Handlers* h2 = upb::pb::GetDecoderHandlers(h, JIT, &h2); |
||||
|
||||
proto2_sink = pipeline.NewSink(h); |
||||
decoder_sink = pipeline.NewSink(h2); |
||||
pipeline.DonateRef(h, &h); |
||||
pipeline.DonateRef(h2, &h2); |
||||
|
||||
upb::pb::Decoder* d = decoder_sink->GetObject<upb::pb::Decoder>(); |
||||
upb::pb::ResetDecoderSink(d, proto2_sink); |
||||
|
||||
return true; |
||||
} |
||||
|
||||
static void cleanup() { |
||||
} |
||||
|
||||
static size_t run(int i) { |
||||
pipeline.Reset(); |
||||
proto2_sink->Reset(&msg[i % NUM_MESSAGES]); |
||||
msg[i % NUM_MESSAGES].Clear(); |
||||
|
||||
if (!upb::PutStringToBytestream(decoder_sink, str, len)) { |
||||
fprintf(stderr, "Decode error: %s", pipeline.status().GetString()); |
||||
return 0; |
||||
} |
||||
return len; |
||||
} |
@ -1,37 +0,0 @@ |
||||
|
||||
#include "main.c" |
||||
#include MESSAGE_HFILE |
||||
#include <string> |
||||
#include <iostream> |
||||
#include <sstream> |
||||
#include <fstream> |
||||
|
||||
static std::string str; |
||||
MESSAGE_CIDENT msg[NUM_MESSAGES]; |
||||
|
||||
static bool initialize() |
||||
{ |
||||
// Read the message data itself. */
|
||||
std::ifstream stream(MESSAGE_FILE); |
||||
if(!stream.is_open()) { |
||||
fprintf(stderr, "Error opening " MESSAGE_FILE ".\n"); |
||||
return false; |
||||
} |
||||
std::stringstream stringstream; |
||||
stringstream << stream.rdbuf(); |
||||
str = stringstream.str(); |
||||
return true; |
||||
} |
||||
|
||||
static void cleanup() |
||||
{ |
||||
} |
||||
|
||||
static size_t run(int i) |
||||
{ |
||||
if(!msg[i%NUM_MESSAGES].ParsePartialFromString(str)) { |
||||
fprintf(stderr, "Error parsing with proto2.\n"); |
||||
return 0; |
||||
} |
||||
return str.size(); |
||||
} |
@ -1,46 +0,0 @@ |
||||
|
||||
#include "main.c" |
||||
#include <google/protobuf/dynamic_message.h> |
||||
#include <iostream> |
||||
#include <sstream> |
||||
#include <fstream> |
||||
#include MESSAGE_HFILE |
||||
|
||||
static std::string str; |
||||
static google::protobuf::DynamicMessageFactory factory; |
||||
static google::protobuf::Message *msg[NUM_MESSAGES]; |
||||
|
||||
static bool initialize() |
||||
{ |
||||
// Read the message data itself.
|
||||
std::ifstream stream(MESSAGE_FILE); |
||||
if(!stream.is_open()) { |
||||
fprintf(stderr, "Error opening " MESSAGE_FILE ".\n"); |
||||
return false; |
||||
} |
||||
std::stringstream stringstream; |
||||
stringstream << stream.rdbuf(); |
||||
str = stringstream.str(); |
||||
|
||||
// Create the DynamicMessage.
|
||||
const google::protobuf::Message *dynamic_msg_prototype = |
||||
factory.GetPrototype(MESSAGE_CIDENT::descriptor()); |
||||
for(int i = 0; i < NUM_MESSAGES; i++) |
||||
msg[i] = dynamic_msg_prototype->New(); |
||||
return true; |
||||
} |
||||
|
||||
static void cleanup() |
||||
{ |
||||
for(int i = 0; i < NUM_MESSAGES; i++) |
||||
delete msg[i]; |
||||
} |
||||
|
||||
static size_t run(int i) |
||||
{ |
||||
if(!msg[i%NUM_MESSAGES]->ParsePartialFromString(str)) { |
||||
fprintf(stderr, "Error parsing with proto2.\n"); |
||||
return 0; |
||||
} |
||||
return str.size(); |
||||
} |
@ -1,15 +0,0 @@ |
||||
// |
||||
// upb - a minimalist implementation of protocol buffers. |
||||
// |
||||
// Copyright (c) 2011 Google Inc. See LICENSE for details. |
||||
// Author: Josh Haberman <jhaberman@gmail.com> |
||||
// |
||||
// A .proto file for the examples in this directory. |
||||
|
||||
package example; |
||||
|
||||
message SampleMessage { |
||||
optional string name = 1; |
||||
optional int32 id = 2; |
||||
optional string email = 3; |
||||
} |
@ -1,59 +0,0 @@ |
||||
/*
|
||||
* upb - a minimalist implementation of protocol buffers. |
||||
* |
||||
* Copyright (c) 2011 Google Inc. See LICENSE for details. |
||||
* Author: Josh Haberman <jhaberman@gmail.com> |
||||
* |
||||
* A simple example that demonstrates creating a standard message object |
||||
* and parsing into it, using a dynamic reflection-based approach. |
||||
* |
||||
* Note that with this approach there are no strongly-typed struct or class |
||||
* definitions to use from C -- this is essentially a reflection-based |
||||
* interface. Note that parsing and serializing are still very fast since |
||||
* they are JIT-based. |
||||
* |
||||
* If this seems a bit verbose, you may prefer an approach that generates |
||||
* strongly-typed struct definitions (upb will likely provide this, but it is |
||||
* not yet implemented). |
||||
* |
||||
* TODO: make this file compiled as part of "make examples" |
||||
* TODO: test that this actually works (WARNING: UNTESTED!) |
||||
*/ |
||||
|
||||
#include "upb/msg.h" |
||||
#include "upb/pb/glue.h" |
||||
|
||||
const char *descfile = "example.proto.pb"; |
||||
const char *type = "example.SampleMessage"; |
||||
const char *msgfile = "sample_message.pb"; |
||||
|
||||
int main() { |
||||
// First we load the descriptor that describes the message into a upb_msgdef.
|
||||
// This could come from a string that is compiled into the program or from a
|
||||
// separate file as we do here. Since defs always live in a symtab, we
|
||||
// create one of those also.
|
||||
upb_symtab *s = upb_symtab_new(); |
||||
upb_status status = UPB_STATUS_INIT; |
||||
if (!upb_load_descriptor_file_into_symtab(s, descfile, &status)) { |
||||
fprintf(stderr, "Couldn't load descriptor file '%s': %s\n", descfile, |
||||
upb_status_getstr(&status)); |
||||
return -1; |
||||
} |
||||
|
||||
const upb_msgdef *md = upb_symtab_lookupmsg(s, type); |
||||
if (!md) { |
||||
fprintf(stderr, "Descriptor did not contain type '%s'\n", type); |
||||
return -1; |
||||
} |
||||
|
||||
// Parse a file into a new message object.
|
||||
void *msg = upb_filetonewmsg(msgfile, md, &status); |
||||
if (!msg) { |
||||
fprintf(stderr, "Error parsing message file '%s': %s\n", msgfile, |
||||
upb_status_getstr(&status)); |
||||
return -1; |
||||
} |
||||
|
||||
// TODO: Inspect some fields.
|
||||
return 0; |
||||
} |
@ -1,76 +0,0 @@ |
||||
|
||||
#include <stdlib.h> |
||||
#include "upb/bytestream.h" |
||||
#include "upb/pb/decoder.h" |
||||
#include "upb/pb/glue.h" |
||||
#include "upb/pb/textprinter.h" |
||||
|
||||
int main(int argc, char *argv[]) { |
||||
if (argc < 3) { |
||||
fprintf(stderr, "Usage: stream_transcode <descfile> <msgname>\n"); |
||||
return 1; |
||||
} |
||||
|
||||
upb_symtab *symtab = upb_symtab_new(); |
||||
size_t desc_len; |
||||
const char *desc = upb_readfile(argv[1], &desc_len); |
||||
if (!desc) { |
||||
fprintf(stderr, "Couldn't open descriptor file: %s\n", argv[1]); |
||||
return 1; |
||||
} |
||||
|
||||
upb_status status = UPB_STATUS_INIT; |
||||
upb_load_descriptor_into_symtab(symtab, desc, desc_len, &status); |
||||
if (!upb_ok(&status)) { |
||||
fprintf(stderr, "Error parsing descriptor: %s", upb_status_getstr(&status)); |
||||
return 1; |
||||
} |
||||
free((void*)desc); |
||||
|
||||
const upb_def *md = upb_symtab_lookup(symtab, argv[2]); |
||||
if (!md) { |
||||
fprintf(stderr, "Descriptor did not contain message: %s\n", argv[2]); |
||||
return 1; |
||||
} |
||||
|
||||
const upb_msgdef *m = upb_dyncast_msgdef_const(md); |
||||
if (!m) { |
||||
fprintf(stderr, "Def was not a msgdef.\n"); |
||||
return 1; |
||||
} |
||||
|
||||
upb_stdio in, out; |
||||
upb_stdio_init(&in); |
||||
upb_stdio_init(&out); |
||||
upb_stdio_reset(&in, stdin); |
||||
upb_stdio_reset(&out, stdout); |
||||
|
||||
upb_handlers *handlers = upb_handlers_new(); |
||||
upb_textprinter *p = upb_textprinter_new(); |
||||
upb_textprinter_reset(p, upb_stdio_bytesink(&out), false); |
||||
upb_textprinter_reghandlers(handlers, m); |
||||
|
||||
upb_decoder d; |
||||
upb_decoder_init(&d, handlers); |
||||
upb_decoder_reset(&d, upb_stdio_bytesrc(&in), 0, UPB_NONDELIMITED, p); |
||||
|
||||
upb_status_clear(&status); |
||||
upb_decoder_decode(&d, &status); |
||||
|
||||
if (!upb_ok(&status)) { |
||||
fprintf(stderr, "Error parsing input: %s", upb_status_getstr(&status)); |
||||
} |
||||
|
||||
upb_status_uninit(&status); |
||||
upb_stdio_uninit(&in); |
||||
upb_stdio_uninit(&out); |
||||
upb_decoder_uninit(&d); |
||||
upb_textprinter_free(p); |
||||
upb_def_unref(UPB_UPCAST(m)); |
||||
upb_symtab_unref(symtab); |
||||
|
||||
// Prevent C library from holding buffers open, so Valgrind doesn't see
|
||||
// memory leaks.
|
||||
fclose(stdin); |
||||
fclose(stdout); |
||||
} |
Loading…
Reference in new issue