|
| 1 | +import random |
| 2 | +import string |
| 3 | + |
| 4 | +import pyperf |
| 5 | + |
| 6 | +from ddtrace.internal.encoding import Encoder |
| 7 | +from ddtrace.span import Span |
| 8 | + |
| 9 | + |
| 10 | +try: |
| 11 | + # the introduction of the buffered encoder changed the internal api |
| 12 | + # see https://github.com/DataDog/dd-trace-py/pull/2422 |
| 13 | + from ddtrace.internal._encoding import BufferedEncoder # noqa: F401 |
| 14 | + |
| 15 | + def _init_encoder(max_size=8 << 20, max_item_size=8 << 20): |
| 16 | + return Encoder(max_size, max_item_size) |
| 17 | + |
| 18 | + |
| 19 | +except ImportError: |
| 20 | + |
| 21 | + def _init_encoder(): |
| 22 | + return Encoder() |
| 23 | + |
| 24 | + |
| 25 | +VARIANTS = [ |
| 26 | + dict(ntraces=1, nspans=1000), |
| 27 | + dict(ntraces=100, nspans=1000), |
| 28 | + dict(ntraces=1, nspans=1000, ntags=1, ltags=16), |
| 29 | + dict(ntraces=1, nspans=1000, ntags=48, ltags=64), |
| 30 | + dict(ntraces=1, nspans=1000, nmetrics=1), |
| 31 | + dict(ntraces=1, nspans=1000, nmetrics=48), |
| 32 | +] |
| 33 | + |
| 34 | + |
| 35 | +def _rands(size=6, chars=string.ascii_uppercase + string.digits): |
| 36 | + return "".join(random.choice(chars) for _ in range(size)) |
| 37 | + |
| 38 | + |
| 39 | +def _random_values(k, size): |
| 40 | + if k == 0: |
| 41 | + return [] |
| 42 | + |
| 43 | + return list(set([_rands(size=size) for _ in range(k)])) |
| 44 | + |
| 45 | + |
| 46 | +def _gen_data(ntraces=1, nspans=1, ntags=0, ltags=0, nmetrics=0): |
| 47 | + traces = [] |
| 48 | + |
| 49 | + # choose from a set of randomly generated span attributes |
| 50 | + span_names = _random_values(256, 16) |
| 51 | + resources = _random_values(256, 16) |
| 52 | + services = _random_values(16, 16) |
| 53 | + tag_keys = _random_values(ntags, 16) |
| 54 | + metric_keys = _random_values(nmetrics, 16) |
| 55 | + |
| 56 | + for _ in range(ntraces): |
| 57 | + trace = [] |
| 58 | + for i in range(0, nspans): |
| 59 | + # first span is root so has no parent otherwise parent is root span |
| 60 | + parent_id = trace[0].span_id if i > 0 else None |
| 61 | + span_name = random.choice(span_names) |
| 62 | + resource = random.choice(resources) |
| 63 | + service = random.choice(services) |
| 64 | + with Span(None, span_name, resource=resource, service=service, parent_id=parent_id) as span: |
| 65 | + if ntags > 0: |
| 66 | + span.set_tags(dict(zip(tag_keys, [_rands(size=ltags) for _ in range(ntags)]))) |
| 67 | + if nmetrics > 0: |
| 68 | + span.set_metrics( |
| 69 | + dict( |
| 70 | + zip( |
| 71 | + metric_keys, |
| 72 | + [random.randint(0, 2 ** 16) for _ in range(nmetrics)], |
| 73 | + ) |
| 74 | + ) |
| 75 | + ) |
| 76 | + trace.append(span) |
| 77 | + traces.append(trace) |
| 78 | + return traces |
| 79 | + |
| 80 | + |
| 81 | +def time_encode(loops, variant): |
| 82 | + encoder = _init_encoder() |
| 83 | + traces = _gen_data(**variant) |
| 84 | + range_it = range(loops) |
| 85 | + t0 = pyperf.perf_counter() |
| 86 | + for _ in range_it: |
| 87 | + encoder.encode_traces(traces) |
| 88 | + dt = pyperf.perf_counter() - t0 |
| 89 | + return dt |
| 90 | + |
| 91 | + |
| 92 | +if __name__ == "__main__": |
| 93 | + runner = pyperf.Runner() |
| 94 | + for variant in VARIANTS: |
| 95 | + name = "|".join(f"{k}:{v}" for (k, v) in variant.items()) |
| 96 | + runner.bench_time_func("scenario:encoder|" + name, time_encode, variant) |
0 commit comments