Documents
performance
performance
Type
External
Status
Published
Created
Mar 7, 2026
Updated
Mar 7, 2026
Source
View

Performance#

Stringy is designed for efficient analysis of binary files, from small executables to large system libraries. This guide covers performance characteristics, optimization techniques, and best practices.

Performance Overview#

Typical Performance#

File SizeProcessing TimeMemory UsageNotes
< 1MB< 100ms< 10MBSmall executables
1-10MB100ms - 1s10-50MBTypical applications
10-100MB1-10s50-200MBLarge applications, libraries
> 100MB10s+200MB+System libraries, packed files

Factors Affecting Performance#

  1. File size: Larger files take longer to process
  2. Section count: More sections require more analysis
  3. String density: Files with many strings take longer
  4. Encoding complexity: UTF-16 detection is more expensive than ASCII
  5. Classification depth: More semantic patterns increase processing time

Memory Management#

Memory Mapping#

Stringy uses memory mapping for efficient file access:

// Automatic memory mapping for large files
if file_size > MEMORY_MAP_THRESHOLD {
    let mmap = unsafe { Mmap::map(&file)? };
    process_data(&mmap[..])
} else {
    let data = std::fs::read(path)?;
    process_data(&data)
}

Benefits:

  • Reduced memory usage for large files
  • Faster access to file data
  • OS-level caching optimization

Configuration:

# Adjust memory mapping threshold
stringy --mmap-threshold 5MB large_file.exe

# Disable memory mapping
stringy --no-mmap file.exe

Memory Usage Patterns#

Peak Memory = Base Memory + File Size + String Storage + Classification Data
  • Base Memory: ~5-10MB for the application
  • File Size: Full file size if not memory-mapped
  • String Storage: ~2-5x the total extracted string length
  • Classification Data: ~1-2MB for regex engines and caches

Memory Optimization#

# Limit string length to reduce memory usage
stringy --max-len 200 large_file.exe

# Limit results to reduce output memory
stringy --top 100 large_file.exe

# Process specific sections only
stringy --sections .rodata,.rdata large_file.exe

CPU Performance#

Single-Threaded Performance#

Core extraction pipeline is optimized for single-threaded performance:

  1. Section Analysis: O(n) where n = number of sections
  2. String Extraction: O(m) where m = total section size
  3. Classification: O(k) where k = number of extracted strings
  4. Ranking: O(k log k) for sorting

Parallel Processing#

Future versions will support parallel processing:

// Planned parallel section processing
sections.par_iter()
    .flat_map(|section| extract_from_section(section, data))
    .collect()

Parallelization opportunities:

  • Section-level extraction
  • Classification of string batches
  • Multiple file processing

CPU Optimization Techniques#

Regex Caching#

lazy_static! {
    static ref URL_REGEX: Regex = Regex::new(r"https?://[^\s]+").unwrap();
    static ref DOMAIN_REGEX: Regex = Regex::new(r"[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}").unwrap();
}

Efficient String Scanning#

// Optimized ASCII scanning with SIMD potential
fn scan_ascii_optimized(data: &[u8]) -> Vec<StringMatch> {
    let mut matches = Vec::new();
    let mut current_start = None;

    for (i, &byte) in data.iter().enumerate() {
        if is_printable_ascii(byte) {
            if current_start.is_none() {
                current_start = Some(i);
            }
        } else if let Some(start) = current_start.take() {
            if i - start >= MIN_LENGTH {
                matches.push(StringMatch { start, end: i });
            }
        }
    }

    matches
}

I/O Performance#

File Access Patterns#

Stringy uses sequential access patterns optimized for modern storage:

// Sequential section processing
for section in container.sections {
    let section_data = &data[section.offset..section.offset + section.size];
    process_section(section_data);
}

Storage Type Impact#

Storage TypeRelative PerformanceNotes
NVMe SSD1.0x (baseline)Optimal performance
SATA SSD0.8-0.9xGood performance
HDD0.3-0.5xSlower, especially for large files
Network0.1-0.3xHighly variable

I/O Optimization#

# Process from faster storage when possible
cp /slow/path/binary /tmp/binary
stringy /tmp/binary

# Use memory mapping for network files
stringy --force-mmap network_file.exe

Optimization Strategies#

For Interactive Use#

Optimize for fast feedback:

# Quick scan of high-value sections
stringy --sections .rodata,.rdata --top 20 binary.exe

# ASCII only for faster processing
stringy --enc ascii --min-len 6 binary.exe

# Skip expensive classification
stringy --no-classify --json binary.exe | jq '.[] | select(.length > 10)'

For Batch Processing#

Optimize for throughput:

# Process multiple files efficiently
find /binaries -name "*.exe" -exec stringy --json {} \; > all_strings.jsonl

# Use minimal output for large batches
stringy --json --no-metadata --top 10 *.dll

# Parallel processing with xargs
find /binaries -name "*.so" | xargs -P 4 -I {} stringy --json {} > results.jsonl

For Large Files#

Handle large files efficiently:

# Focus on high-value sections
stringy --sections .rodata,.rdata,.rsrc huge_file.exe

# Increase minimum length to reduce noise
stringy --min-len 8 --top 50 huge_file.exe

# Use streaming output for very large results
stringy --json huge_file.exe | head -1000 > sample.jsonl

Performance Monitoring#

Built-in Timing#

# Enable timing information
stringy --timing binary.exe

Output includes:

  • File loading time
  • Format detection time
  • Section analysis time
  • String extraction time
  • Classification time
  • Output formatting time

Memory Profiling#

# Monitor memory usage (Unix systems)
/usr/bin/time -v stringy large_file.exe

# macOS
/usr/bin/time -l stringy large_file.exe

Benchmarking#

Use the built-in benchmark suite:

# Run performance benchmarks
cargo bench

# Benchmark specific components
cargo bench --bench extraction
cargo bench --bench classification

Performance Tuning#

Configuration Tuning#

[performance]
# Memory mapping threshold (bytes)
memory_map_threshold = 10485760 # 10MB

# Maximum memory usage (bytes)
max_memory_usage = 1073741824 # 1GB

# String extraction chunk size
chunk_size = 1048576 # 1MB

# Enable performance optimizations
fast_mode = true
skip_low_confidence = true

Runtime Tuning#

# Adjust for available memory
export STRINGY_MAX_MEMORY=512MB

# Tune for CPU cores
export STRINGY_THREADS=4

# Enable aggressive caching
export STRINGY_CACHE_SIZE=100MB

Bottleneck Analysis#

Common Bottlenecks#

  1. Large UTF-16 sections: UTF-16 detection is CPU-intensive
  2. Many small strings: Classification overhead per string
  3. Complex regex patterns: Some semantic patterns are expensive
  4. Large output: JSON serialization and formatting

Profiling Tools#

# CPU profiling with perf (Linux)
perf record --call-graph dwarf stringy large_file.exe
perf report

# Memory profiling with valgrind
valgrind --tool=massif stringy binary.exe

# macOS profiling with Instruments
instruments -t "Time Profiler" stringy binary.exe

Optimization Examples#

Fast Security Scan#

# Optimized for security indicators
stringy \
  --enc ascii,utf8 \
  --min-len 8 \
  --only url,domain,ipv4,filepath \
  --top 20 \
  --sections .rodata,.rdata \
  malware.exe

Comprehensive Analysis#

# Thorough but efficient analysis
stringy \
  --enc ascii,utf16le \
  --min-len 4 \
  --max-len 500 \
  --top 200 \
  --json \
  application.exe > analysis.jsonl

Batch Processing Script#

#!/bin/bash
# Efficient batch processing

TEMP_DIR=$(mktemp -d)
trap "rm -rf $TEMP_DIR" EXIT

for file in "$@"; do
    # Copy to fast storage if needed
    if [[ "$file" == /slow/* ]]; then
        cp "$file" "$TEMP_DIR/"
        file="$TEMP_DIR/$(basename "$file")"
    fi

    # Process with optimized settings
    stringy \
      --json \
      --top 50 \
      --min-len 6 \
      --sections .rodata,.rdata,.rsrc \
      "$file" >> results.jsonl
done

Future Optimizations#

Planned Improvements#

  1. SIMD acceleration: Vectorized string scanning
  2. Parallel processing: Multi-threaded extraction and classification
  3. Incremental analysis: Cache results for repeated analysis
  4. Streaming processing: Handle arbitrarily large files
  5. GPU acceleration: Parallel pattern matching on GPU

Performance Roadmap#

  • v0.2: Basic parallel processing
  • v0.3: SIMD-optimized string scanning
  • v0.4: Incremental analysis and caching
  • v1.0: Full streaming support

This performance guide helps you get the most out of Stringy for your specific use case, whether you're doing interactive analysis or processing large batches of files.

performance | Dosu