1

I have a spam detection mechanism which searches strings of word in posts. The List can be 500+ entries long sometimes. I have a naïve searching algorithm

//Unnecessary logic have been removed
public static filter(List < FeedItem > feeds, Boolean extractSpam) {

        List < String > spamWords = CommunitySpamFilter.getSpamWords();// List of words (can be long sometimes)
        for (FeedItem feed: feeds) {
            String comment = feed.Type == 'QuestionPost'?feed.Title +' '+feed.body : feed.body;
            Set < String > spamDetected = new Set < String > ();
            for (String spamWord: spamWords) {
                Pattern myPattern = Pattern.compile('(.*)(' + spamWord + ')(.*)');
                Matcher myMatcher = myPattern.matcher(comment);
                if (myMatcher.matches()) {
                    spamDetected.add(spamWord);
                }
            }
        }
    }

I need to optimize it for performance, are there any suggestions?

1 Answer 1

0

String#contains() is very likely to be faster than a regular expression match (but you should benchmark to be sure!)

The bigger optimization opportunity, though, is available if you can assume that spam words are single words (not phrases or sub-word units or strings containing non-alphanumeric characters). If that's the case, you can preprocess your input into a Set of words and quickly compare to your spam words list. It would look something like this:

public static filter(List < FeedItem > feeds, Boolean extractSpam) {

        Set < String > spamWords = new Set<String>(CommunitySpamFilter.getSpamWords());
        
// List of words (can be long sometimes)
        for (FeedItem feed: feeds) {
            String comment = feed.Type == 'QuestionPost' ? feed.Title + ' ' + feed.body : feed.body;
            // You can definitely refine this regex; just an example.
            Set<String> wordsInComment = new Set<String>(
                comment.split('[^a-zA-Z]')
            );
            wordsInComment.retainAll(spamWords);
            Boolean hasSpam = !wordsInComment.isEmpty();
        }
    }

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .