Ruby_python_string_methods

proc bulk_upcase(arr: cstringArray, len: cint) {.exportc, dynlib, cdecl.} =
  for i in 0 ..< len:
    let s = cast[ptr UncheckedArray[char]](arr[i])
    if s == nil: continue
    var j = 0
    
    while s[j] != '\0':
      if s[j] >= 'a' and s[j] <= 'z':
        s[j] = chr(ord(s[j]) - 32)
      inc j
require 'ffi'

module NimLib
  extend FFI::Library
  ffi_lib './libfast_string.so'

  attach_function :bulk_upcase, [:pointer, :int], :void
end

data = ('a'..'z').to_a.map { |c| "  #{c * 500}  " } * 500

pointers = data.map { |s| FFI::MemoryPointer.from_string(s) }
ptr_array = FFI::MemoryPointer.new(:pointer, pointers.size)
ptr_array.write_array_of_pointer(pointers)

NimLib.bulk_upcase(ptr_array, pointers.size)

puts "Resultat för första strängen:"
puts pointers.first.read_string[0..50]

# results = pointers.map(&:read_string)

Benchmark Results:

Method Time
Python native .upper() 0.0070s
Ruby native .upcase 0.052s
Ruby + Nim (FFI) 0.0039s

Observations:

  • Ruby + Nim is 13x faster than Ruby native
  • Python native is 7x faster than Ruby native
  • Ruby + Nim beats Python, being 1.8x faster