Skip to content

Performance of b64 encoding/decoding #10

@vincentjames501

Description

@vincentjames501

I'd like to say this is a great pure Lua approach to doing b64 encoding/decoding. We really need this to do b32 decoding and b64 url safe decoding and finding that easily in other modules is a challenge!

When compared to other modules (such as https://github.com/iskolbin/lbase64), the encoding/decoding performance looks like it could use some attention. I don't do much Lua so not sure how much help I would be here. Here is a benchmark on my M2 MBP:

basexx = require "basexx"
base64 = require "base64"

local units = {
    ['seconds'] = 1,
    ['milliseconds'] = 1000,
    ['microseconds'] = 1000000,
    ['nanoseconds'] = 1000000000
}

function benchmark(unit, decPlaces, n, f, ...)
    local elapsed = 0
    local multiplier = units[unit]
    for i = 1, n do
        local now = os.clock()
        f(...)
        elapsed = elapsed + (os.clock() - now)
    end
    print(string.format('Benchmark results: %d function calls | %.'.. decPlaces ..'f %s elapsed | %.'.. decPlaces ..'f %s avg execution time.', n, elapsed * multiplier, unit, (elapsed / n) * multiplier, unit))
end

print("Benchmarking base64.decode...")

benchmark('milliseconds', 5, 10000, base64.decode, "TWFuIGlzIGRpc3Rpbmd1aXNoZWQsIG5vdCBvbmx5IGJ5IGhpcyByZWFzb24sIGJ1dCBieSB0aGlzIHNpbmd1bGFyIHBhc3Npb24gZnJvbSBvdGhlciBhbmltYWxzLCB3aGljaCBpcyBhIGx1c3Qgb2YgdGhlIG1pbmQsIHRoYXQgYnkgYSBwZXJzZXZlcmFuY2Ugb2YgZGVsaWdodCBpbiB0aGUgY29udGludWVkIGFuZCBpbmRlZmF0aWdhYmxlIGdlbmVyYXRpb24gb2Yga25vd2xlZGdlLCBleGNlZWRzIHRoZSBzaG9ydCB2ZWhlbWVuY2Ugb2YgYW55IGNhcm5hbCBwbGVhc3VyZS4=")

print("Benchmarking basexx.from_base64...")

benchmark('milliseconds', 5, 10000, basexx.from_base64, "TWFuIGlzIGRpc3Rpbmd1aXNoZWQsIG5vdCBvbmx5IGJ5IGhpcyByZWFzb24sIGJ1dCBieSB0aGlzIHNpbmd1bGFyIHBhc3Npb24gZnJvbSBvdGhlciBhbmltYWxzLCB3aGljaCBpcyBhIGx1c3Qgb2YgdGhlIG1pbmQsIHRoYXQgYnkgYSBwZXJzZXZlcmFuY2Ugb2YgZGVsaWdodCBpbiB0aGUgY29udGludWVkIGFuZCBpbmRlZmF0aWdhYmxlIGdlbmVyYXRpb24gb2Yga25vd2xlZGdlLCBleGNlZWRzIHRoZSBzaG9ydCB2ZWhlbWVuY2Ugb2YgYW55IGNhcm5hbCBwbGVhc3VyZS4=")

print("Benchmarking base64.encode...")

benchmark('milliseconds', 5, 10000, base64.encode, "Man is distinguished, not only by his reason, but by this singular passion from other animals, which is a lust of the mind, that by a perseverance of delight in the continued and indefatigable generation of knowledge, exceeds the short vehemence of any carnal pleasure.")

print("Benchmarking basexx.to_base64...")

benchmark('milliseconds', 5, 10000, basexx.to_base64, "Man is distinguished, not only by his reason, but by this singular passion from other animals, which is a lust of the mind, that by a perseverance of delight in the continued and indefatigable generation of knowledge, exceeds the short vehemence of any carnal pleasure.")

Results:

Benchmarking base64.decode...
Benchmark results: 10000 function calls | 259.39300 milliseconds elapsed | 0.02594 milliseconds avg execution time.
Benchmarking basexx.from_base64...
Benchmark results: 10000 function calls | 5682.15300 milliseconds elapsed | 0.56822 milliseconds avg execution time.
Benchmarking base64.encode...
Benchmark results: 10000 function calls | 219.74300 milliseconds elapsed | 0.02197 milliseconds avg execution time.
Benchmarking basexx.to_base64...
Benchmark results: 10000 function calls | 5304.85800 milliseconds elapsed | 0.53049 milliseconds avg execution time.

So it's around 20-25x slower. Any thoughts on what can be done to improve the performance?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions