I went through sub-classes of AbstractFunction and removed synchronization where it is not required.
Basically, if a function does not modify state and if it accesses thread-safe objects only, then synchronization is not required.

Please find the attached patch on top of e9228ccf / trunk@1632410.

Notes:
0) The patch contains just synchronization removal + some corrections to CV. All the tests pass except testPropfile(org.apache.jmeter.save.TestSaveService)junit.framework.AssertionFailedError: Property File Version mismatch, ensure you update SaveService#FILEVERSION field with revision id of saveservice.properties.

testPropfile fails without patch as well, so I did not investigate that.

1) I have no idea what to do with BeanShell function. bsh.Interpreter is thread safe, however bshInterpreter.set("vars",...) should not be accessed concurrently as that will just overwrite the value.
I think it makes sense to wrap bsh interpreter in a ThreadLocal, so synchronization can be removed from BeanShell.execute

2) There are lots of cases when Thread.currentThread().getName() is used. This method always creates new String, thus it has performance impact (see [1]).

2.1) ThreadNumber function even tries to parse thread name. It would be great if ThreadNumber can be implemented via JMeterContextService.getContext().getThreadNum().

2.2) Other usages of currentThread.getName() might probably be replaced with JMeterContextService.getContext().getThread().getThreadName()

3) __time function parses regexp "/\\d+" in the execute. I guess it might make sense to move that to setParameters.

[1]: https://bugs.openjdk.java.net/browse/JDK-8059677

Vladimir Sitnikov