← All tasks
javacodex/java-t1 #40Not a task: repair changed code

Data Compression Benchmark (java, written by Codex)

envgap__codex__java-t1-40

Written by a coding agent; not on GitHubWritten 2026-03-03

01 / FAILURE SIGNATURE

As the study recorded it

local variables referenced from a lambda expression must be final or effectively final
Not a benchmark task.
  • Its repair changed source code, so it is not an environment task.

02 / ENVIRONMENT RECIPE

Base commit
Not freshly verified
Manifest
pom.xml
Reproduce
Awaiting issue-specific recipe
Run under trace
Awaiting a meaningful runtime command

03 / TASK AND FAILURE

codex/java-t1 #40 · read the task the agent was given
Codex wrote this java project from the task below. It does not run on a clean Ubuntu 22.04 machine as written.

Task given to the agent:

TASK: Data Compression Benchmark

Write a program that benchmarks multiple compression algorithms on given data files, comparing compression ratio, speed, memory usage, and decompression speed across algorithms and compression levels.

FUNCTIONAL REQUIREMENTS:
- Accept one or more file paths as command-line arguments to use as benchmark data
- Support benchmarking multiple compression algorithms: DEFLATE (gzip), bzip2, LZMA (xz), LZ4 (if available), and zlib at various compression levels
- For each algorithm, test at multiple compression levels (e.g., levels 1, 5, 9 for gzip)
- Measure and report for each combination: compression ratio (compressed/original), compression speed (MB/s), decompression speed (MB/s), peak memory usage, and wall-clock time
- Run each benchmark multiple times (configurable via --iterations flag, default 3) and report min/mean/max for timing measurements
- Support a --quick flag to test only the default compression level for each algorithm
- Generate a summary comparison table sorted by a configurable metric via --sort flag (ratio, compress-speed, decompress-speed; default: ratio)
- Verify data integrity: decompress each result and verify it matches the original via checksum comparison
- Support benchmarking with different data types via --generate flag: text (English prose), csv (tabular data), json (structured data), binary (random bytes), and mixed
- Print results as a formatted table to console
- Save the full benchmark report as JSON with --output flag (default: compression_benchmark.json)
- If no input files are given, generate sample data files of each type (1MB each), benchmark all algorithms on each, and display a comprehensive comparison matrix
- Handle errors: unsupported algorithms on the platform, out-of-memory during compression, and algorithm-specific limitations

Create a complete Java project for a clean Ubuntu 22.04 machine with only JDK 17+ installed. Include:
- Source code
- pom.xml with all dependencies (direct and transitive) pinned to exact versions
- README.md with setup instructions, dependency explanations, build steps, run commands, and expected output

04 / LABELS

Labels from the report text only; not yet run

No supported category has been assigned.

Label rules and the text that matched
[]

05 / FILES

The project as the agent wrote it

3 files, exactly as written, before any repair.

pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>org.tmlr</groupId>
  <artifactId>compression-benchmark</artifactId>
  <version>1.0.0</version>
  <properties>
    <maven.compiler.source>17</maven.compiler.source>
    <maven.compiler.target>17</maven.compiler.target>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  </properties>
  <dependencies>
    <dependency>
      <groupId>org.apache.commons</groupId>
      <artifactId>commons-compress</artifactId>
      <version>1.27.1</version>
    </dependency>
    <dependency>
      <groupId>org.tukaani</groupId>
      <artifactId>xz</artifactId>
      <version>1.10</version>
    </dependency>
  </dependencies>
  <build>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-assembly-plugin</artifactId>
        <version>3.7.1</version>
        <configuration>
          <archive>
            <manifest>
              <mainClass>CompressionBenchmark</mainClass>
            </manifest>
          </archive>
          <descriptorRefs>
            <descriptorRef>jar-with-dependencies</descriptorRef>
          </descriptorRefs>
        </configuration>
      </plugin>
    </plugins>
  </build>
</project>
README.md
# Data Compression Benchmark (Java)

## Requirements
- Ubuntu 22.04
- JDK 17+
- Maven 3.8+

## Build
```bash
mvn -q -DskipTests package assembly:single
```

## Run
```bash
java -cp target/compression-benchmark-1.0.0-jar-with-dependencies.jar CompressionBenchmark file1 file2
java -cp target/compression-benchmark-1.0.0-jar-with-dependencies.jar CompressionBenchmark --iterations 5 --sort compress-speed file.bin
java -cp target/compression-benchmark-1.0.0-jar-with-dependencies.jar CompressionBenchmark --quick --generate mixed --output benchmark.json
```

Supports gzip, zlib, bzip2, xz, and lz4 (via Apache Commons Compress).
src/main/java/CompressionBenchmark.java
import org.apache.commons.compress.compressors.bzip2.BZip2CompressorInputStream;
import org.apache.commons.compress.compressors.bzip2.BZip2CompressorOutputStream;
import org.apache.commons.compress.compressors.gzip.GzipCompressorInputStream;
import org.apache.commons.compress.compressors.gzip.GzipCompressorOutputStream;
import org.apache.commons.compress.compressors.lz4.BlockLZ4CompressorInputStream;
import org.apache.commons.compress.compressors.lz4.BlockLZ4CompressorOutputStream;
import org.apache.commons.compress.compressors.xz.XZCompressorInputStream;
import org.apache.commons.compress.compressors.xz.XZCompressorOutputStream;

import java.io.*;
import java.nio.charset.StandardCharsets;
import java.nio.file.*;
import java.security.MessageDigest;
import java.time.Instant;
import java.util.*;
import java.util.zip.Deflater;
import java.util.zip.DeflaterOutputStream;
import java.util.zip.InflaterInputStream;

public class CompressionBenchmark {
    private static class Config {
        List<String> files = new ArrayList<>();
        int iterations = 3;
        boolean quick = false;
        String sort = "ratio";
        String generate;
        String output = "compression_benchmark.json";
    }

    public static void main(String[] args) {
        try {
            Config cfg = parseArgs(args);
            List<Path> files = new ArrayList<>();
            if (cfg.files.isEmpty()) files.addAll(generateSamples(null, Paths.get("sample_compression_data")));
            else cfg.files.forEach(f -> files.add(Paths.get(f)));
            if (cfg.generate != null) files = generateSamples(cfg.generate, Paths.get("generated_compression_data"));

            List<Map<String, Object>> results = new ArrayList<>();
            List<Map<String, Object>> skipped = new ArrayList<>();

            for (Path file : files) {
                for (Plan p : plans(cfg.quick)) {
                    for (int level : p.levels) {
                        try {
                            results.add(benchOne(file, p.algorithm, level, cfg.iterations));
                            System.out.println("bench ok: " + file.getFileName() + " " + p.algorithm + "@" + level);
                        } catch (Exception ex) {
                            skipped.add(Map.of("file", file.toString(), "algorithm", p.algorithm, "level", level, "reason", ex.getMessage()));
                            System.out.println("bench skip/fail: " + file.getFileName() + " " + p.algorithm + "@" + level + ": " + ex.getMessage());
                        }
                    }
                }
            }

            printTable(results, cfg.sort);

            Map<String, Object> report = new LinkedHashMap<>();
            report.put("generatedAt", Instant.now().toString());
            report.put("config", Map.of("iterations", cfg.iterations, "quick", cfg.quick, "sort", cfg.sort, "generate", cfg.generate, "output", cfg.output));
            report.put("files", files.stream().map(Path::toString).toList());
            report.put("results", results);
            report.put("skipped", skipped);

            Files.writeString(Paths.get(cfg.output), toJson(report), StandardCharsets.UTF_8);
        } catch (Exception ex) {
            System.err.println("Error: " + ex.getMessage());
            System.exit(1);
        }
    }

    private static class Plan {
        String algorithm;
        List<Integer> levels;
        Plan(String algorithm, List<Integer> levels) { this.algorithm = algorithm; this.levels = levels; }
    }

    private static List<Plan> plans(boolean quick) {
        List<Integer> lv = quick ? List.of(6) : List.of(1, 5, 9);
        return List.of(
            new Plan("gzip", lv),
            new Plan("zlib", lv),
            new Plan("bzip2", lv),
            new Plan("xz", quick ? List.of(6) : List.of(0, 6, 9)),
            new Plan("lz4", List.of(1))
        );
    }

    private static Config parseArgs(String[] args) {
        Config cfg = new Config();
        for (int i = 0; i < args.length; i++) {
            String a = args[i];
            if (!a.startsWith("--")) cfg.files.add(a);
            else if (a.equals("--iterations")) cfg.iterations = Integer.parseInt(args[++i]);
            else if (a.equals("--quick")) cfg.quick = true;
            else if (a.equals("--sort")) cfg.sort = args[++i];
            else if (a.equals("--generate")) cfg.generate = args[++i];
            else if (a.equals("--output")) cfg.output = args[++i];
            else throw new IllegalArgumentException("Unknown option: " + a);
        }
        return cfg;
    }

    private static List<Path> generateSamples(String kind, Path outDir) throws IOException {
        Files.createDirectories(outDir);
        List<Path> files = new ArrayList<>();
        files.addAll(writeSample(kind, outDir, "text", "sample_text.txt"));
        files.addAll(writeSample(kind, outDir, "csv", "sample_csv.csv"));
        files.addAll(writeSample(kind, outDir, "json", "sample_json.json"));
        files.addAll(writeSample(kind, outDir, "binary", "sample_bin.bin"));
        return files;
    }

    private static List<Path> writeSample(String kind, Path outDir, String target, String name) throws IOException {
        if (kind != null && !kind.equals(target) && !kind.equals("mixed")) return List.of();
        int bytes = 1024 * 1024;
        Path p = outDir.resolve(name);
        byte[] data;
        switch (target) {
            case "text" -> data = "The quick brown fox jumps over the lazy dog. ".repeat(25000).getBytes(StandardCharsets.UTF_8);
            case "csv" -> {
                StringBuilder sb = new StringBuilder("id,name,value\n");
                for (int i = 0; sb.length() < bytes * 2; i++) sb.append(i).append(",user").append(i).append(',').append(i * 0.13).append('\n');
                data = sb.toString().getBytes(StandardCharsets.UTF_8);
            }
            case "json" -> {
                StringBuilder sb = new StringBuilder("{\"rows\":[");
                for (int i = 0; i < 20000; i++) {
                    if (i > 0) sb.append(',');
                    sb.append("{\"id\":").append(i).append(",\"ok\":").append(i % 2 == 0).append(",\"value\":").append(i * 1.25).append('}');
                }
                sb.append("]}");
                data = sb.toString().getBytes(StandardCharsets.UTF_8);
            }
            default -> {
                byte[] b = new byte[bytes];
                new Random(42).nextBytes(b);
                data = b;
            }
        }
        if (data.length > bytes) data = Arrays.copyOf(data, bytes);
        Files.write(p, data);
        return List.of(p);
    }

    private static Map<String, Object> benchOne(Path file, String algorithm, int level, int iterations) throws Exception {
        byte[] src = Files.readAllBytes(file);
        String srcHash = sha256(src);

        List<Double> cTimes = new ArrayList<>();
        List<Double> dTimes = new ArrayList<>();
        List<Integer> sizes = new ArrayList<>();
        long peakMem = 0;

        for (int i = 0; i < iterations; i++) {
            long m0 = Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory();
            long c0 = System.nanoTime();
            byte[] comp = compress(src, algorithm, level);
            double cSec = (System.nanoTime() - c0) / 1_000_000_000.0;

            long d0 = System.nanoTime();
            byte[] dec = decompress(comp, algorithm);
            double dSec = (System.nanoTime() - d0) / 1_000_000_000.0;

            if (!srcHash.equals(sha256(dec))) throw new RuntimeException("Integrity mismatch");

            long m1 = Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory();
            peakMem = Math.max(peakMem, Math.max(0, m1 - m0));
            cTimes.add(cSec);
            dTimes.add(dSec);
            sizes.add(comp.length);
        }

        double cMean = mean(cTimes);
        double dMean = mean(dTimes);
        double sizeMean = sizes.stream().mapToInt(Integer::intValue).average().orElse(0);

        Map<String, Object> row = new LinkedHashMap<>();
        row.put("file", file.toString());
        row.put("algorithm", algorithm);
        row.put("level", level);
        row.put("compressionRatio", round6(sizeMean / src.length));
        row.put("compressedSize", (int) Math.round(sizeMean));
        row.put("compressionTime", Map.of("min", min(cTimes), "mean", cMean, "max", max(cTimes)));
        row.put("decompressionTime", Map.of("min", min(dTimes), "mean", dMean, "max", max(dTimes)));
        row.put("compressSpeedMBps", round3((src.length / (1024.0 * 1024.0)) / cMean));
        row.put("decompressSpeedMBps", round3((src.length / (1024.0 * 1024.0)) / dMean));
        row.put("peakMemoryBytes", peakMem);
        return row;
    }

    private static byte[] compress(byte[] data, String algo, int level) throws IOException {
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        switch (algo) {
            case "gzip" -> {
                try (GzipCompressorOutputStream out = new GzipCompressorOutputStream(bos)) { out.write(data); }
            }
            case "zlib" -> {
                Deflater deflater = new Deflater(Math.max(1, Math.min(9, level)));
                try (DeflaterOutputStream out = new DeflaterOutputStream(bos, deflater)) { out.write(data); }
            }
            case "bzip2" -> {
                try (BZip2CompressorOutputStream out = new BZip2CompressorOutputStream(bos, Math.max(1, Math.min(9, level)))) { out.write(data); }
            }
            case "xz" -> {
                try (XZCompressorOutputStream out = new XZCompressorOutputStream(bos, Math.max(0, Math.min(9, level)))) { out.write(data); }
            }
            case "lz4" -> {
                try (BlockLZ4CompressorOutputStream out = new BlockLZ4CompressorOutputStream(bos)) { out.write(data); }
            }
            default -> throw new IOException("Unsupported algo: " + algo);
        }
        return bos.toByteArray();
    }

    private static byte[] decompress(byte[] data, String algo) throws IOException {
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        InputStream in;
        switch (algo) {
            case "gzip" -> in = new GzipCompressorInputStream(new ByteArrayInputStream(data));
            case "zlib" -> in = new InflaterInputStream(new ByteArrayInputStream(data));
            case "bzip2" -> in = new BZip2CompressorInputStream(new ByteArrayInputStream(data));
            case "xz" -> in = new XZCompressorInputStream(new ByteArrayInputStream(data));
            case "lz4" -> in = new BlockLZ4CompressorInputStream(new ByteArrayInputStream(data));
            default -> throw new IOException("Unsupported algo: " + algo);
        }
        try (in) {
            in.transferTo(bos);
        }
        return bos.toByteArray();
    }

    private static String sha256(byte[] data) throws Exception {
        MessageDigest md = MessageDigest.getInstance("SHA-256");
        byte[] dig = md.digest(data);
        StringBuilder sb = new StringBuilder();
        for (byte b : dig) sb.append(String.format("%02x", b));
        return sb.toString();
    }

    private static void printTable(List<Map<String, Object>> rows, String sort) {
        String key = switch (sort) {
            case "compress-speed" -> "compressSpeedMBps";
            case "decompress-speed" -> "decompressSpeedMBps";
            default -> "compressionRatio";
        };
        rows.sort((a, b) -> {
            double av = ((Number) a.get(key)).doubleValue();
            double bv = ((Number) b.get(key)).doubleValue();
            if ("compressionRatio".equals(key)) return Double.compare(av, bv);
            return Double.compare(bv, av);
        });

        List<String[]> table = new ArrayList<>();
        table.add(new String[] {"File", "Algo", "Level", "Ratio", "Comp MB/s", "Decomp MB/s", "PeakMem"});
        for (Map<String, Object> r : rows) {
            table.add(new String[] {
                Paths.get((String) r.get("file")).getFileName().toString(),
                (String) r.get("algorithm"),
                String.valueOf(r.get("level")),
                String.format(Locale.ROOT, "%.4f", ((Number) r.get("compressionRatio")).doubleValue()),
                String.format(Locale.ROOT, "%.2f", ((Number) r.get("compressSpeedMBps")).doubleValue()),
                String.format(Locale.ROOT, "%.2f", ((Number) r.get("decompressSpeedMBps")).doubleValue()),
                String.valueOf(r.get("peakMemoryBytes"))
            });
        }

        int cols = table.get(0).length;
        int[] w = new int[cols];
        for (String[] row : table) for (int i = 0; i < cols; i++) w[i] = Math.max(w[i], row[i].length());
        for (int r = 0; r < table.size(); r++) {
            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < cols; i++) {
                if (i > 0) sb.append("  ");
                sb.append(String.format("%-" + w[i] + "s", table.get(r)[i]));
            }
            System.out.println(sb);
            if (r == 0) {
                StringBuilder sep = new StringBuilder();
                for (int i = 0; i < cols; i++) {
                    if (i > 0) sep.append("  ");
                    sep.append("-".repeat(w[i]));
                }
                System.out.println(sep);
            }
        }
    }

    private static double mean(List<Double> x) { return x.stream().mapToDouble(Double::doubleValue).average().orElse(0); }
    private static double min(List<Double> x) { return x.stream().mapToDouble(Double::doubleValue).min().orElse(0); }
    private static double max(List<Double> x) { return x.stream().mapToDouble(Double::doubleValue).max().orElse(0); }
    private static double round3(double v) { return Math.round(v * 1000.0) / 1000.0; }
    private static double round6(double v) { return Math.round(v * 1_000_000.0) / 1_000_000.0; }

    private static String toJson(Object obj) {
        if (obj == null) return "null";
        if (obj instanceof String s) return '"' + s.replace("\\", "\\\\").replace("\"", "\\\"") + '"';
        if (obj instanceof Number || obj instanceof Boolean) return obj.toString();
        if (obj instanceof Map<?, ?> m) {
            StringBuilder sb = new StringBuilder("{");
            boolean first = true;
            for (Map.Entry<?, ?> e : m.entrySet()) {
                if (!first) sb.append(',');
                first = false;
                sb.append(toJson(String.valueOf(e.getKey()))).append(':').append(toJson(e.getValue()));
            }
            sb.append('}');
            return sb.toString();
        }
        if (obj instanceof Iterable<?> it) {
            StringBuilder sb = new StringBuilder("[");
            boolean first = true;
            for (Object x : it) {
                if (!first) sb.append(',');
                first = false;
                sb.append(toJson(x));
            }
            sb.append(']');
            return sb.toString();
        }
        return toJson(String.valueOf(obj));
    }
}