strcspn

Benchmark created on


Setup

// Most efficient for general use - Set-based O(n+m)
function strcspn(str, reject) {
    const rejectSet = new Set(reject);
    
    for (let i = 0; i < str.length; i++) {
        if (rejectSet.has(str[i])) {
            return i;
        }
    }
    return str.length;
}

// Alternative: Simple loop - better for very small reject strings
function strcspnSimple(str, reject) {
    for (let i = 0; i < str.length; i++) {
        if (reject.includes(str[i])) {
            return i;
        }
    }
    return str.length;
}

// Functional approach using findIndex
function strcspnFunctional(str, reject) {
    const rejectSet = new Set(reject);
    const index = [...str].findIndex(char => rejectSet.has(char));
    return index === -1 ? str.length : index;
}

// RegExp-based approach - good for complex patterns
function strcspnRegExp(str, reject) {
    // Escape special regex characters
    const escapedReject = reject.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
    const regex = new RegExp(`[${escapedReject}]`);
    const match = str.search(regex);
    return match === -1 ? str.length : match;
}

// Optimized version that chooses strategy based on input size
function strcspnOptimized(str, reject) {
    // For very small reject strings, simple includes() can be faster
    // due to less overhead than creating a Set
    if (reject.length <= 3) {
        for (let i = 0; i < str.length; i++) {
            if (reject.includes(str[i])) {
                return i;
            }
        }
        return str.length;
    }
    
    // For larger reject strings, use Set for O(1) lookups
    const rejectSet = new Set(reject);
    for (let i = 0; i < str.length; i++) {
        if (rejectSet.has(str[i])) {
            return i;
        }
    }
    return str.length;
}

    const testStr = "The quick brown fox jumps over the lazy dog".repeat(1000);
    const testReject = "aeiou";
    const iterations = 100;
    

Test runner

Ready to run.

Testing in
TestOps/sec
fnal
	for (let i = 0; i < iterations; i++) {
        strcspnFunctional(testStr, testReject);
	}
ready
simple
    for (let i = 0; i < iterations; i++) {
        strcspnSimple(testStr, testReject);
    }
ready
regexp
    for (let i = 0; i < iterations; i++) {
        strcspnRegExp(testStr, testReject);
    }
ready
simple/set
    for (let i = 0; i < iterations; i++) {
        strcspnOptimized(testStr, testReject);
    }
ready

Revisions

You can edit these tests or add more tests to this page by appending /edit to the URL.