StoreStreamClob.getReader(charPos) performs poorly because it resets the underlying stream and skips data until it reached the requested character position. Not only does the data has to be skipped, it also has to be decoded (UTF-8).
The problem is exposed through EmbedClob.getSubString, which causes extremely bad performance for the client driver because the locator based Clob implementation uses this method.
For the record, there is another read buffer size issue that exaggerates the problem (it will probably be handled under
DERBY-3769, and also DERBY-3818).