Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 12 additions & 1 deletion .agents/skills/perf-review/references/guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,18 @@ every call. Fix: `static final Pattern`.

**`String.format` / format-string parsing.** Re-parses and allocates per call. Fix: direct
concatenation, or pre-compute the result. Also watch for locale-dependent formatting crossing the
wire — a correctness issue on top of the perf one.
wire - a correctness issue on top of the perf one.

**Explicit locales and charsets.**

- Overloads that use an implicit locale or charset are forbidden.
- Use:
- `Strings.format(...)` for machine-readable formatting where `internal-api` is available.
- `Locale.ROOT` for case conversion and direct JDK formatting.
- The protocol's charset, usually `StandardCharsets.UTF_8`, for byte conversions.
- An explicit JVM default or a narrowly scoped `@SuppressForbidden`, with a comment explaining
why the default is intentional.
- `Strings.format(...)` retains `String.format`'s parsing and allocation costs.

**`Config.get()` per call.** Walks a config-resolution chain; not a free read. Fix: hoist to a
`static final` field at class initialization. This is the single most recurring DBM finding —
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ public static boolean isZulu8() {
}

public static boolean isGraalVM() {
return runtime.vendorVersion.toLowerCase().contains("graalvm");
return runtime.vendorVersion.toLowerCase(Locale.ROOT).contains("graalvm");
}

public static String getLangVersion() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,11 @@
import static java.util.Locale.ROOT;

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
Expand Down Expand Up @@ -88,7 +90,10 @@ public static boolean isMusl() {
}

private static boolean isMuslProcSelfMaps() throws IOException {
try (BufferedReader reader = new BufferedReader(new FileReader("/proc/self/maps"))) {
try (BufferedReader reader =
new BufferedReader(
new InputStreamReader(
new FileInputStream("/proc/self/maps"), StandardCharsets.ISO_8859_1))) {
String line;
while ((line = reader.readLine()) != null) {
if (line.contains("-musl-")) {
Expand Down
18 changes: 15 additions & 3 deletions components/json/src/main/java/datadog/json/JsonReader.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;

/**
Expand Down Expand Up @@ -490,22 +491,33 @@ private String readLiteral(int length) throws IOException {
private IOException unexpectedSyntaxError(String expected, String found) {
return new IOException(
String.format(
Locale.ROOT,
"Syntax error at line %d, position %d: expected %s but found '%s'",
this.lineNumber, this.linePosition, expected, found));
this.lineNumber,
this.linePosition,
expected,
found));
}

private IOException unexpectedSyntaxError(String expected, char found) {
return new IOException(
String.format(
Locale.ROOT,
"Syntax error at line %d, position %d: expected %s but found '%s'",
this.lineNumber, this.linePosition, expected, found));
this.lineNumber,
this.linePosition,
expected,
found));
}

private IOException syntaxError(String message) {
return new IOException(
String.format(
Locale.ROOT,
"Syntax error at line %d, position %d: %s",
this.lineNumber, this.linePosition, message));
this.lineNumber,
this.linePosition,
message));
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
import datadog.trace.bootstrap.instrumentation.api.AgentTracer;
import datadog.trace.bootstrap.instrumentation.api.ClientIpAddressData;
import datadog.trace.bootstrap.instrumentation.api.Tags;
import datadog.trace.util.Strings;
import java.io.IOException;
import java.lang.annotation.Annotation;
import java.lang.reflect.Type;
Expand Down Expand Up @@ -108,7 +109,7 @@ public static void install() {
}
String endpoint = config.getAiGuardEndpoint();
if (isBlank(endpoint)) {
endpoint = String.format("https://app.%s/api/v2/ai-guard", config.getSite());
endpoint = Strings.format("https://app.%s/api/v2/ai-guard", config.getSite());
}
final Map<String, String> headers =
mapOf(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.URL;
import java.nio.charset.StandardCharsets;
Expand Down Expand Up @@ -51,14 +52,18 @@ public class InjectingPipeOutputStreamBenchmark {
public void withPipe() throws Exception {
try (final PrintWriter out =
new PrintWriter(
new InjectingPipeOutputStream(new ByteArrayOutputStream(), marker, content))) {
new OutputStreamWriter(
new InjectingPipeOutputStream(new ByteArrayOutputStream(), marker, content),
StandardCharsets.UTF_8))) {
htmlContent.forEach(out::println);
}
}

@Benchmark
public void withoutPipe() throws Exception {
try (final PrintWriter out = new PrintWriter(new ByteArrayOutputStream())) {
try (final PrintWriter out =
new PrintWriter(
new OutputStreamWriter(new ByteArrayOutputStream(), StandardCharsets.UTF_8))) {
htmlContent.forEach(out::println);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,10 @@
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.nio.charset.StandardCharsets;
import java.util.Objects;
import org.slf4j.Logger;
Expand All @@ -30,7 +31,10 @@ public class StaticEventLogger {
String fileName = dir + "startup_" + System.currentTimeMillis() + ".csv";

try {
writer = new BufferedWriter(new FileWriter(fileName), 32768);
writer =
new BufferedWriter(
new OutputStreamWriter(new FileOutputStream(fileName), StandardCharsets.UTF_8),
32768);
writer.write("Event,State,Timestamp");
writer.newLine();
} catch (IOException e) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ private static String getCommitMessage(String messageSubject, String messageBody
if (messageBody == null) {
return messageSubject;
}
return String.format("%s%n%s", messageSubject, messageBody);
return Strings.format("%s%n%s", messageSubject, messageBody);
}

@Override
Expand Down Expand Up @@ -126,13 +126,13 @@ private String buildGitCommit() {

private String buildGitRepositoryUrl(final String repoProvider, final String repoName) {
if ("github".equals(repoProvider) && (repoName != null && !repoName.isEmpty())) {
return String.format("https://github.com/%s.git", repoName);
return Strings.format("https://github.com/%s.git", repoName);
}
return null;
}

private String buildPipelineUrl(final String repoName, final String buildId) {
return String.format("https://ci.appveyor.com/project/%s/builds/%s", repoName, buildId);
return Strings.format("https://ci.appveyor.com/project/%s/builds/%s", repoName, buildId);
}

private PersonInfo buildGitCommitAuthor() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import datadog.trace.api.git.GitInfo;
import datadog.trace.api.git.PersonInfo;
import datadog.trace.civisibility.ci.env.CiEnvironment;
import datadog.trace.util.Strings;
import javax.annotation.Nonnull;

class AzurePipelinesInfo implements CIProviderInfo {
Expand Down Expand Up @@ -144,12 +145,12 @@ private String buildCiJobUrl(
final String buildId,
final String jobId,
final String taskId) {
return String.format(
return Strings.format(
"%s%s/_build/results?buildId=%s&view=logs&j=%s&t=%s", uri, project, buildId, jobId, taskId);
}

private String buildCiPipelineUrl(final String uri, final String project, final String buildId) {
return String.format("%s%s/_build/results?buildId=%s", uri, project, buildId);
return Strings.format("%s%s/_build/results?buildId=%s", uri, project, buildId);
}

private PersonInfo buildGitCommitAuthor() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ public PullRequestInfo buildPullRequestInfo() {
}

private String buildPipelineUrl(final String repo, final String number) {
return String.format(
return Strings.format(
"https://bitbucket.org/%s/addon/pipelines/home#!/results/%s", repo, number);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import datadog.trace.api.git.GitInfo;
import datadog.trace.api.git.PersonInfo;
import datadog.trace.civisibility.ci.env.CiEnvironment;
import datadog.trace.util.Strings;
import javax.annotation.Nonnull;

class BuddyInfo implements CIProviderInfo {
Expand Down Expand Up @@ -80,7 +81,7 @@ private String getPipelineId(String pipelineNumber) {
if (pipelineNumber == null) {
return pipelineId;
}
return String.format("%s/%s", pipelineId, pipelineNumber);
return Strings.format("%s/%s", pipelineId, pipelineNumber);
}

private PersonInfo buildGitCommiter() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import datadog.trace.api.git.GitInfo;
import datadog.trace.api.git.PersonInfo;
import datadog.trace.civisibility.ci.env.CiEnvironment;
import datadog.trace.util.Strings;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
Expand Down Expand Up @@ -73,7 +74,7 @@ public CIInfo buildCIInfo() {
.ciPipelineNumber(environment.get(BUILDKITE_PIPELINE_NUMBER))
.ciPipelineUrl(ciPipelineUrl)
.ciJobId(environment.get(BUILDKITE_JOB_ID))
.ciJobUrl(String.format("%s#%s", ciPipelineUrl, environment.get(BUILDKITE_JOB_ID)))
.ciJobUrl(Strings.format("%s#%s", ciPipelineUrl, environment.get(BUILDKITE_JOB_ID)))
.ciWorkspace(expandTilde(environment.get(BUILDKITE_WORKSPACE_PATH)))
.ciNodeName(environment.get(BUILDKITE_AGENT_ID))
.ciNodeLabels(buildCiNodeLabels())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import datadog.trace.api.git.CommitInfo;
import datadog.trace.api.git.GitInfo;
import datadog.trace.civisibility.ci.env.CiEnvironment;
import datadog.trace.util.Strings;
import javax.annotation.Nonnull;

class CircleCIInfo implements CIProviderInfo {
Expand Down Expand Up @@ -71,7 +72,7 @@ private String buildPipelineUrl(final String pipelineId) {
return null;
}

return String.format("https://app.circleci.com/pipelines/workflows/%s", pipelineId);
return Strings.format("https://app.circleci.com/pipelines/workflows/%s", pipelineId);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -204,25 +204,25 @@ private String buildGitRepositoryUrl(final String host, final String repo) {
return null;
}

return String.format("%s/%s.git", host, repo);
return Strings.format("%s/%s.git", host, repo);
}

private String buildPipelineUrl(
final String host, final String repo, final String pipelineId, final String retry) {
if (retry != null && !retry.isEmpty()) {
return String.format("%s/%s/actions/runs/%s/attempts/%s", host, repo, pipelineId, retry);
return Strings.format("%s/%s/actions/runs/%s/attempts/%s", host, repo, pipelineId, retry);
} else {
return String.format("%s/%s/actions/runs/%s", host, repo, pipelineId);
return Strings.format("%s/%s/actions/runs/%s", host, repo, pipelineId);
}
}

private String buildJobUrl(final String host, final String repo, final String commit) {
return String.format("%s/%s/commit/%s/checks", host, repo, commit);
return Strings.format("%s/%s/commit/%s/checks", host, repo, commit);
}

private String buildJobUrlWithNumericId(
final String host, final String repo, final String pipelineId, final String jobId) {
return String.format("%s/%s/actions/runs/%s/job/%s", host, repo, pipelineId, jobId);
return Strings.format("%s/%s/actions/runs/%s/job/%s", host, repo, pipelineId, jobId);
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import datadog.trace.api.git.GitInfo;
import datadog.trace.api.git.PersonInfo;
import datadog.trace.civisibility.ci.env.CiEnvironment;
import datadog.trace.util.Strings;
import javax.annotation.Nonnull;

class TravisInfo implements CIProviderInfo {
Expand Down Expand Up @@ -100,7 +101,7 @@ private String buildGitRepositoryUrl() {
if (repoSlug == null || repoSlug.isEmpty()) {
return null;
}
return String.format("https://github.com/%s.git", repoSlug);
return Strings.format("https://github.com/%s.git", repoSlug);
}

private String buildCiPipelineName() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import datadog.trace.civisibility.ipc.Signal;
import datadog.trace.civisibility.ipc.SignalResponse;
import datadog.trace.civisibility.ipc.SignalType;
import datadog.trace.util.Strings;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Function;
Expand Down Expand Up @@ -41,7 +42,7 @@ public SignalResponse onModuleSignalReceived(ModuleSignal result) {
moduleHandlersById.get(moduleId);
if (handlersByType == null) {
String message =
String.format(
Strings.format(
"Could not find signal handlers for module ID %s, test execution result will be ignored: %s",
moduleId, result);
LOGGER.warn(message);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@

import de.thetaphi.forbiddenapis.SuppressForbidden;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;

Expand All @@ -30,7 +32,9 @@ private void load(final String path) {
// url = https://some-host/user/repository.git
// fetch = +refs/heads/*:refs/remotes/origin/*

try (final BufferedReader br = new BufferedReader(new FileReader(path))) {
try (final BufferedReader br =
new BufferedReader(
new InputStreamReader(new FileInputStream(path), StandardCharsets.UTF_8))) {
String line;
String section = null;
while ((line = br.readLine()) != null) {
Expand Down
Loading
Loading