liquidev / euwren

High-level Wren wrapper for Nim
MIT License
36 stars 0 forks source link

Exception handling in foreign procs #12

Closed liquidev closed 4 years ago

liquidev commented 4 years ago

Any exceptions thrown by foreign procs should be handled and produce a wrenAbortFiber call. Currently, this isn't done out of performance concerns, but I'll do some benchmarks to see whether the cost of a try…except block is that significant.

liquidev commented 4 years ago

I just finished testing. Here are the results:

noTry(): 
  total = 189.844138 ms
  average = 1014.440180000031 ns
tryNoExcept(): 
  total = 188.843723 ms
  average = 1011.482229999894 ns
tryExcept(): 
  total = 355.960725 ms
  average = 2640.988000000115 ns

Here's the code used to test:

import times

var s = ""

proc noTry() =
  s.add("test")

proc tryNoExcept() =
  try:
    s.add("test")
  except:
    s.add("test")

proc tryExcept() =
  try:
    raise newException(Exception, "nope")
  except:
    s.add("test")

const Iterations = 100_000
template measureTime(expr) =
  let start = cpuTime()
  var avg = 0.0
  for i in 1..Iterations:
    let iterStart = cpuTime()
    expr
    avg += cpuTime() - iterStart
  avg /= Iterations
  echo astToStr(expr), ": "
  echo "  total = ", (cpuTime() - start) * 1_000, " ms"
  echo "  average = ", avg * 1_000_000_000, " ns"

measureTime noTry()
measureTime tryNoExcept()
measureTime tryExcept()

# prevent s from being optimized out
writeFile("/dev/null", s)

Tests were conducted on the Nim playground.

In conclusion, just entering a try block is cheap. It's except that really costs, so it shouldn't be a problem to just wrap all bound procs in try…except.

liquidev commented 4 years ago

Fixed in 0.9.0.