We have the following system in place:
No of Users : ~500k
No of Items : ~100k
UserSimilarity userSimilarity = new TanimotoCoefficientSimilarity(dataModel);
UserNeighborhood neighborhood = new NearestNUserNeighborhood(neighborHoodSize,userSimilarity, dataModel);
GenericBooleanPrefUserBasedRecommender recommender = new GenericBooleanPrefUserBasedRecommender(dataModel, neighborhood ,userSimilarity);
With the above recommender we were getting a response time with an average of 600ms for 400 neighbourhood size.
We tried making it to less than 100ms(online engine) and we did achieve this by using custom TopItems.getTopUsers() and TopItems.getTopItems() multithreaded(equal to no of cores) functions. Avg time taken for the functions
TopUsers(): ~ 30-40 ms
TopItems(): ~ 50-60 ms
However, when we tried to make many concurrent requests (even to order of 25), the response time shoots up to seconds.
We could afford to precompute something like the neighbourhood for each user but TopItems() still is a clear bottleneck for concurrent requests.
Would you suggest any way to improve response time for concurrent requests with multithreading?
The fallback option would be to store precomputed recommendations in some NoSql DB. This is going to be little expensive as we precompute on a regular basis even for not so active users. We could probably pick active users and precompute recommendations more often than that of not-so-active users.
Any thoughts?