So I can't comment to add to Terry's answer, but .Q.ts runs -34!, which means it's only going to time the aj lambda of this:
q)0N!.z.P;r:.Q.ts[{aj0[`sym`time;enlist `sym`time!(`MSFT;0D09:30:00);x]};enlist select from trade where date=.z.D-1];0N!.z.P;
Terry has answered about the memory mapping vs read/copy and I would agree with him there.
For your specific example of a single timestamp search have you tried using asof instead of aj?
Both aj and asof use binary search under covers, with aj having a number of utility enhancements for applying either fill or join depending on which version of aj you are using.
Binary search is covered in the documentation. The top two links from the search bar for me are:
https://code.kx.com/q/basics/by-topic/#search which list topics that explore searching in arrays in general.
https://code.kx.com/q/ref/bin/ which is specifically about bin which is the function which does the hard work in asof and aj