Reputation: 11999
I have list and I need to check whether it contains 2 specific string or not. I have the below code and looking to optimise it further
fun isContentTVE_AVOD(subscriptionPlans: List<ContentDatum>): Boolean {
var tve = false
var avod = false
if (subscriptionPlans.size > 0) {
for (i in subscriptionPlans.indices) {
if (subscriptionPlans[i] != null &&
subscriptionPlans[i].planMonetizationModel != null) {
if (subscriptionPlans[i].planMonetizationModel.equals("TVE", ignoreCase = true)) tve = true
if (subscriptionPlans[i].planMonetizationModel.equals("AVOD", ignoreCase = true)) avod = true
}
}
}
return tve && avod
}
Upvotes: 1
Views: 579
Reputation: 18547
What are you trying to optimise for?
My natural reaction would be to start with the simplest code, which is along the lines of:
fun isContentTVE_AVOD(subscriptionPlans: List<ContentDatum>)
= "TVE" in subscriptionPlans
&& "AVOD" in subscriptionPlans
That's simple, easy to read and understand (pretty close to how you'd describe the function), and hard to get wrong. So it'll save you time — and whoever has to debug and maintain and enhance your code. It's usually far better to keep things simple wherever possible.
It's also likely to be a little faster than your implementation. Partly because the two in
checks will stop when they find a match, rather than continuing along the rest of the list. But partly because it's simpler — not just your code, but the library routines it's calling will be simpler, so the runtime will have more scope to optimise them. And also because they'll be called more often, so the runtime will have more opportunity to optimise them. (The JVM can do a lot of optimisation, perhaps better than you can. It's usually better to keep your code clear and straightforward to give it the best chance.)
If you think you need it to be faster still, then the first thing would be to do some performance testing, to show whether time spent in that function is really making that much difference to your overall runtime. (Which seems pretty unlikely in the vast majority of cases.)
If you've shown that that function really is a bottleneck, then tweaking the implementation probably isn't going to gain very much. However it works, you'll still need to scan through most of the list, on average, making it O(n) — and that complexity will usually outweigh any constant-factor improvements.
So if you do spend a lot of time in that function, then I'd try to change the design, not the implementation.
For example, if you made your subscriptionPlans
a Set
instead of a List
, then you could probably do a lookup in constant time without iterating through the list at all. (And the code above would work just the same with, except for changing the type!)
Or if you need a list (to preserve the order and/or duplicates), you could use a custom list wrapper which maintained counts of the two values, and updated them when adding/modifying/removing items from the list. Obviously that would be most appropriate if you make these checks more often than you modify the list (and known in advance which values you'll be checking for).
Upvotes: 2
Reputation: 1088
If it is repeated process or use-case.
Try this:-
Time Complexity :- O(1).
If you list consists of a custom objects, as it appears here, you can try managing the count inside the model class while you are creating the object or while setting the various features and simultaneously increment the count whenever the match is found.
Upvotes: 0
Reputation: 4039
You can use find
,any
or filter
methods. Please check below for any
method applied:
fun isContentTVE_AVOD(subscriptionPlans: List<ContentDatum>): Boolean {
var tve = subscriptionPlans.any { it.planMonetizationModel?.equals("TVE") }
var avod = subscriptionPlans.any { it.planMonetizationModel?.equals("AVOD") }
return tve && avod
}
Upvotes: 3
Reputation: 1875
fun isContentTVE_AVOD(subscriptionPlans: List<ContentDatum>): Boolean {
var tve = false
var avod = false
if (subscriptionPlans.size > 0) {
for (i in subscriptionPlans.indices) {
if (subscriptionPlans[i] != null &&
subscriptionPlans[i].planMonetizationModel != null) {
if (subscriptionPlans[i].planMonetizationModel.equals("TVE", ignoreCase = true) && subscriptionPlans[i].planMonetizationModel.equals("AVOD", ignoreCase = true)) {
return true;
}
}
}
}
return false;
}
Upvotes: 0