/* * Copyright 2014-2017 Netflix, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.netflix.spectator.perf; import com.netflix.spectator.api.DefaultRegistry; import com.netflix.spectator.api.Id; import com.netflix.spectator.api.Registry; import org.openjdk.jmh.annotations.Benchmark; import org.openjdk.jmh.annotations.Scope; import org.openjdk.jmh.annotations.State; import org.openjdk.jmh.annotations.Threads; import org.openjdk.jmh.infra.Blackhole; import java.util.HashMap; import java.util.Map; /** * <pre> * Benchmark Mode Cnt Score Error Units * Ids.append1 thrpt 10 24,832,015.561 ± 775914.547 ops/s * Ids.append2 thrpt 10 15,115,152.153 ± 500615.433 ops/s * Ids.append4 thrpt 10 5,082,342.853 ± 118696.678 ops/s * Ids.append4sorted thrpt 10 6,243,473.482 ± 203665.016 ops/s * Ids.baseline thrpt 10 17,854,792.417 ± 663244.744 ops/s * Ids.justName thrpt 10 160,126,776.622 ± 8846354.045 ops/s * Ids.withTag thrpt 10 1,696,380.648 ± 35774.917 ops/s * Ids.withTagsMap thrpt 10 2,080,491.447 ± 35497.396 ops/s * Ids.withTagsVararg thrpt 10 2,142,907.363 ± 53384.402 ops/s * Ids.withTagsVarargSorted thrpt 10 4,234,550.555 ± 130956.068 ops/s * </pre> */ @State(Scope.Thread) public class Ids { private final Registry registry = new DefaultRegistry(); private final Map<String, String> tags = getTags(); private Map<String, String> getTags() { Map<String, String> m = new HashMap<>(); m.put( "nf.app", "test_app"); m.put("nf.cluster", "test_app-main"); m.put( "nf.asg", "test_app-main-v042"); m.put( "nf.stack", "main"); m.put( "nf.ami", "ami-0987654321"); m.put( "nf.region", "us-east-1"); m.put( "nf.zone", "us-east-1e"); m.put( "nf.node", "i-1234567890"); m.put( "country", "US"); m.put( "device", "xbox"); m.put( "status", "200"); m.put( "client", "ab"); return m; } private final Id baseId = registry.createId("http.req.complete") .withTag( "nf.app", "test_app") .withTag("nf.cluster", "test_app-main") .withTag( "nf.asg", "test_app-main-v042") .withTag( "nf.stack", "main") .withTag( "nf.ami", "ami-0987654321") .withTag( "nf.region", "us-east-1") .withTag( "nf.zone", "us-east-1e") .withTag( "nf.node", "i-1234567890"); @Threads(1) @Benchmark public void justName(Blackhole bh) { bh.consume(registry.createId("http.req.complete")); } @Threads(1) @Benchmark public void baseline(Blackhole bh) { PrependId id = new PrependId("http.req.complete", null) .withTag( "nf.app", "test_app") .withTag("nf.cluster", "test_app-main") .withTag( "nf.asg", "test_app-main-v042") .withTag( "nf.stack", "main") .withTag( "nf.ami", "ami-0987654321") .withTag( "nf.region", "us-east-1") .withTag( "nf.zone", "us-east-1e") .withTag( "nf.node", "i-1234567890") .withTag( "country", "US") .withTag( "device", "xbox") .withTag( "status", "200") .withTag( "client", "ab"); bh.consume(id); } @Threads(1) @Benchmark public void withTag(Blackhole bh) { Id id = registry.createId("http.req.complete") .withTag( "nf.app", "test_app") .withTag("nf.cluster", "test_app-main") .withTag( "nf.asg", "test_app-main-v042") .withTag( "nf.stack", "main") .withTag( "nf.ami", "ami-0987654321") .withTag( "nf.region", "us-east-1") .withTag( "nf.zone", "us-east-1e") .withTag( "nf.node", "i-1234567890") .withTag( "country", "US") .withTag( "device", "xbox") .withTag( "status", "200") .withTag( "client", "ab"); bh.consume(id); } @Threads(1) @Benchmark public void withTagsVararg(Blackhole bh) { Id id = registry.createId("http.req.complete").withTags( "nf.app", "test_app", "nf.cluster", "test_app-main", "nf.asg", "test_app-main-v042", "nf.stack", "main", "nf.ami", "ami-0987654321", "nf.region", "us-east-1", "nf.zone", "us-east-1e", "nf.node", "i-1234567890", "country", "US", "device", "xbox", "status", "200", "client", "ab"); bh.consume(id); } @Threads(1) @Benchmark public void withTagsVarargSorted(Blackhole bh) { Id id = registry.createId("http.req.complete").withTags( "client", "ab", "country", "US", "device", "xbox", "nf.ami", "ami-0987654321", "nf.app", "test_app", "nf.asg", "test_app-main-v042", "nf.cluster", "test_app-main", "nf.node", "i-1234567890", "nf.region", "us-east-1", "nf.stack", "main", "nf.zone", "us-east-1e", "status", "200" ); bh.consume(id); } @Threads(1) @Benchmark public void withTagsMap(Blackhole bh) { Id id = registry.createId("http.req.complete").withTags(tags); bh.consume(id); } @Threads(1) @Benchmark public void append1(Blackhole bh) { Id id = baseId.withTag("country", "US"); bh.consume(id); } @Threads(1) @Benchmark public void append2(Blackhole bh) { Id id = baseId.withTags( "country", "US", "device", "xbox"); bh.consume(id); } @Threads(1) @Benchmark public void append4(Blackhole bh) { Id id = baseId.withTags( "country", "US", "device", "xbox", "status", "200", "client", "ab"); bh.consume(id); } @Threads(1) @Benchmark public void append4sorted(Blackhole bh) { Id id = baseId.withTags( "client", "ab", "country", "US", "device", "xbox", "status", "200"); bh.consume(id); } public static class PrependId { public final String name; public final PrependTagList tags; public PrependId(String name, PrependTagList tags) { this.name = name; this.tags = tags; } public PrependId withTag(String k, String v) { return new PrependId(name, new PrependTagList(k, v, tags)); } } public static class PrependTagList { public final String key; public final String value; public final PrependTagList next; public PrependTagList(String key, String value, PrependTagList next) { this.key = key; this.value = value; this.next = next; } } }