-
Notifications
You must be signed in to change notification settings - Fork 4.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
CAMEL-11420-Add contains ignore case operator to simple language #1773
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -672,5 +672,40 @@ public static String trimToNull(final String given) { | |
|
||
return trimmed; | ||
} | ||
|
||
/** | ||
* Checks if the src string contains what | ||
* | ||
* @param src is the source string to be checked | ||
* @param what is the string which will be looked up in the src argument | ||
* @return true/false | ||
*/ | ||
public static boolean containsIgnoreCase(String src, String what) { | ||
if (src == null || what == null) { | ||
return false; | ||
} | ||
|
||
final int length = what.length(); | ||
if (length == 0) { | ||
return true; // Empty string is contained | ||
} | ||
|
||
final char firstLo = Character.toLowerCase(what.charAt(0)); | ||
final char firstUp = Character.toUpperCase(what.charAt(0)); | ||
|
||
for (int i = src.length() - length; i >= 0; i--) { | ||
// Quick check before calling the more expensive regionMatches() method: | ||
final char ch = src.charAt(i); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. According to camel-jmh using four test String you provided, plain regionMatches might be the fastest; Needs to run more iterations probably to get error smaller. Probably should test with cases where there are equal number of falses and trues. Result's ofc depend on the distribution of the data. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Does this work with src=aaa and str is aa. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Sorry, seems to wotk There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Without quick check Run complete. Total time: 00:00:28Benchmark Mode Cnt Score Error Units With quick check Run complete. Total time: 00:00:27Benchmark Mode Cnt Score Error Units There is a slight difference. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You probably need are more iterartions since error is so large. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. With quick check Run complete. Total time: 00:02:54Benchmark Mode Cnt Score Error Units Without quick check Run complete. Total time: 00:02:56Benchmark Mode Cnt Score Error Units There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. still no significant change. i guess it's not easy to measure that simple check. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I had a bug in my tests, that is why results were better. It seems that this optimization is beneficial. |
||
if (ch != firstLo && ch != firstUp) { | ||
continue; | ||
} | ||
|
||
if (src.regionMatches(true, i, what, 0, length)) { | ||
return true; | ||
} | ||
} | ||
|
||
return false; | ||
} | ||
|
||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
/** | ||
* Licensed to the Apache Software Foundation (ASF) under one or more | ||
* contributor license agreements. See the NOTICE file distributed with | ||
* this work for additional information regarding copyright ownership. | ||
* The ASF licenses this file to You under the Apache License, Version 2.0 | ||
* (the "License"); you may not use this file except in compliance with | ||
* the License. You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
package org.apache.camel.itest.jmh; | ||
|
||
import java.util.concurrent.TimeUnit; | ||
|
||
import org.apache.camel.util.StringHelper; | ||
import org.junit.Test; | ||
import org.openjdk.jmh.annotations.Benchmark; | ||
import org.openjdk.jmh.annotations.Level; | ||
import org.openjdk.jmh.annotations.Measurement; | ||
import org.openjdk.jmh.annotations.Mode; | ||
import org.openjdk.jmh.annotations.Scope; | ||
import org.openjdk.jmh.annotations.Setup; | ||
import org.openjdk.jmh.annotations.State; | ||
import org.openjdk.jmh.infra.Blackhole; | ||
import org.openjdk.jmh.runner.Runner; | ||
import org.openjdk.jmh.runner.options.Options; | ||
import org.openjdk.jmh.runner.options.OptionsBuilder; | ||
import org.openjdk.jmh.runner.options.TimeValue; | ||
|
||
/** | ||
* Tests the {@link StringHelper}. | ||
* <p/> | ||
* Thanks to this SO answer: https://stackoverflow.com/questions/30485856/how-to-run-jmh-from-inside-junit-tests | ||
*/ | ||
public class ContainsIgnoreCaseTest { | ||
|
||
@Test | ||
public void launchBenchmark() throws Exception { | ||
Options opt = new OptionsBuilder() | ||
// Specify which benchmarks to run. | ||
// You can be more specific if you'd like to run only one benchmark per test. | ||
.include(this.getClass().getName() + ".*") | ||
// Set the following options as needed | ||
.mode(Mode.All) | ||
.timeUnit(TimeUnit.MICROSECONDS) | ||
.warmupTime(TimeValue.seconds(1)) | ||
.warmupIterations(2) | ||
.measurementTime(TimeValue.seconds(1)) | ||
.measurementIterations(2) | ||
.threads(2) | ||
.forks(1) | ||
.shouldFailOnError(true) | ||
.shouldDoGC(true) | ||
.build(); | ||
|
||
new Runner(opt).run(); | ||
} | ||
|
||
// The JMH samples are the best documentation for how to use it | ||
// http://hg.openjdk.java.net/code-tools/jmh/file/tip/jmh-samples/src/main/java/org/openjdk/jmh/samples/ | ||
@State(Scope.Thread) | ||
public static class BenchmarkState { | ||
@Setup(Level.Trial) | ||
public void initialize() { | ||
} | ||
} | ||
|
||
@Benchmark | ||
@Measurement(batchSize = 1000000) | ||
public void benchmark(BenchmarkState state, Blackhole bh) { | ||
bh.consume(StringHelper.containsIgnoreCase("abc", "A")); | ||
bh.consume(StringHelper.containsIgnoreCase("abc", "aB")); | ||
bh.consume(StringHelper.containsIgnoreCase("abc", "aBc")); | ||
bh.consume(StringHelper.containsIgnoreCase("abc", "ad")); | ||
bh.consume(StringHelper.containsIgnoreCase("abc", "abD")); | ||
bh.consume(StringHelper.containsIgnoreCase("abc", "ABD")); | ||
} | ||
|
||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wonder if this should be
~~
orcontains ignore case
etc