RTrim最速っぽいのを簡単に調べてみた
自宅の環境(CPU:Core2 Duo E6750 メモリ4G)ではStringUtils#stripEnd
が最速らしい。
しかし、会社のPCではguavaが最速でした。
検証したのは、
- 処理時に(メソッド呼ばれる毎に)で毎回Patternのインスタンス生成からやる
- Patternの変数をstaticで持たせてインスタンス生成のコストを減らしたもの
- StringUtils#stripEnd
- CharMatcher#trimTrailingFrom
のどれが一番早いか!です。
結果はこちら。
検証コード
package speedcheck; import com.google.common.base.CharMatcher; import org.apache.commons.lang.StringUtils; import java.util.regex.Matcher; import java.util.regex.Pattern; /** * * @author yushi.koga */ public class SpeedCheck { static Pattern staticPatternForRtrim = Pattern.compile("\\s+$"); /** * @param args the command line arguments */ public static void main(String[] args) { String sampleText = "\"aaaaaa\" "; int max = 25000000; String staticTrimedText = null; System.out.println("original text start from here ->" + "\"aaaaaa\" " + "<-to end is here"); System.out.println("loop times : " + max); System.out.println("======================================="); long staticStarted = System.currentTimeMillis(); for (int i = 0; i < max; i++) { Matcher staticMatcher = staticPatternForRtrim.matcher(sampleText); staticTrimedText = staticMatcher.replaceAll(""); } long staticFinished = System.currentTimeMillis(); System.out.println("staticStarted at " + staticStarted); System.out.println("staticfinished at " + staticFinished); System.out.println("staticPassed time is " + ((staticFinished - staticStarted))); System.out.println("staticTrimedText is " + staticTrimedText + "<- end here"); System.out.println("======================================="); String insideTrimedText = null; long insideStarted = System.currentTimeMillis(); for (int i = 0; i < max; i++) { insideTrimedText = Pattern.compile("\\s+$").matcher(sampleText).replaceAll(""); } long insideFinished = System.currentTimeMillis(); System.out.println("insideStarted at " + insideStarted); System.out.println("insidefinished at " + insideFinished); System.out.println("insidePassed time is " + ((insideFinished - insideStarted))); System.out.println("insideTrimedText is " + insideTrimedText + "<- end here"); System.out.println("======================================="); String commonsTrimedText = null; long commonsStarted = System.currentTimeMillis(); for (int i = 0; i < max; i++) { commonsTrimedText = StringUtils.stripEnd(sampleText," "); } long commonsFinished = System.currentTimeMillis(); System.out.println("commonsStarted at " + commonsStarted); System.out.println("commonsFinished at " + commonsFinished); System.out.println("commonsPassed time is " + ((commonsFinished - commonsStarted))); System.out.println("commonsTrimedText is " + commonsTrimedText + "<- end here"); System.out.println("======================================="); String charMatcherTrimedText = null; long charMatcherStarted = System.currentTimeMillis(); for (int i = 0; i < max; i++) { charMatcherTrimedText = CharMatcher.is(' ').trimTrailingFrom(sampleText); } long charMatcherFinished = System.currentTimeMillis(); System.out.println("quavaStarted at " + charMatcherStarted); System.out.println("quavaFinished at " + charMatcherFinished); System.out.println("quavaPassed time is " + ((charMatcherFinished - charMatcherStarted))); System.out.println("quavaTrimedText is " + charMatcherTrimedText + "<- end here"); System.out.println("======================================="); } }
結果
Executing: gradle :run Arguments: [-PmainClass=speedcheck.SpeedCheck, -c, D:\workspaceForNetBeans\speedcheck\settings.gradle] :compileJava UP-TO-DATE :processResources UP-TO-DATE :classes UP-TO-DATE :run original text start from here ->"aaaaaa" <-to end is here loop times : 25000000 ======================================= staticStarted at 1448538448194 staticfinished at 1448538458284 staticPassed time is 10090 staticTrimedText is "aaaaaa"<- end here ======================================= insideStarted at 1448538458285 insidefinished at 1448538479871 insidePassed time is 21586 insideTrimedText is "aaaaaa"<- end here ======================================= commonsStarted at 1448538479871 commonsFinished at 1448538480760 commonsPassed time is 889 commonsTrimedText is "aaaaaa"<- end here ======================================= quavaStarted at 1448538480760 quavaFinished at 1448538483150 quavaPassed time is 2390 quavaTrimedText is "aaaaaa"<- end here ======================================= BUILD SUCCESSFUL Total time: 35.862 secs
どうしてもNIO2が使えないのでムシャクシャしてやった
仕事でですが、どうしてもJava6の環境で、ファイルの更新管理をするライブラリを作らなきゃいけなかったので、Apache Commons IO使って作ってみた。
参考にしたのはここです。 ありがとうございました。
実際に使うときはもっと修正していますが、サンプルにどうぞ。
ResourceMonitor
package sample.file.monitor.monitor; import java.io.File; import java.io.FileFilter; import java.net.MalformedURLException; import java.net.URI; import java.net.URISyntaxException; import java.net.URL; import org.apache.commons.configuration.ConfigurationException; import org.apache.commons.io.monitor.FileAlterationMonitor; import org.apache.commons.io.monitor.FileAlterationObserver; import org.apache.log4j.Logger; import sample.file.monitor.listner.ResourceListner; import sample.file.monitor.resource.Resource; /** * * @author yushi.koga */ public class ResourceMonitor { static private final ResourceMonitor resourceMonitor = new ResourceMonitor(); static private final Logger log = Logger.getLogger(ResourceMonitor.class); private long refreshDelay = 4000L; private URI monitoringDirectory = null; static private final String MONITORING_FILE = "target.txt"; public static ResourceMonitor getInstance() { return resourceMonitor; } public void setRefreshDelay(long refreshDelay) { this.refreshDelay = refreshDelay; } public void setMonitoringDirectory(URI monitoringDirectory) throws URISyntaxException, MalformedURLException { this.monitoringDirectory = monitoringDirectory; } private ResourceMonitor() { } public void start() throws ConfigurationException, MalformedURLException, Exception { // Guard Clause if (monitoringDirectory == null) { throw new IllegalStateException("Please set monitoring directory"); } // Generate Monitor. Interval is milli seconds. FileAlterationMonitor monitor = new FileAlterationMonitor(refreshDelay); // Generate Observer.Set monitoring directory. final File dir = new File(monitoringDirectory); FileFilter filter = new FileFilter() { @Override public boolean accept(File pathname) { return pathname.getName().equals(MONITORING_FILE); } }; FileAlterationObserver observer = new FileAlterationObserver(dir, filter); // Generate and register Lister to Observer ResourceListner listener = new ResourceListner(); observer.addListener(listener); // Register Observer to Monitor monitor.addObserver(observer); // Start Monitor Resource.load(new URL(monitoringDirectory.toURL(), MONITORING_FILE)); monitor.start(); log.info(this.getClass().getSimpleName() + " started monitoring"); } }
ResourceListner
package sample.file.monitor.listner; import java.io.File; import java.net.MalformedURLException; import org.apache.commons.configuration.ConfigurationException; import org.apache.commons.io.monitor.FileAlterationListenerAdaptor; import org.apache.log4j.Logger; import sample.file.monitor.resource.Resource; /** * * @author yushi.koga */ public class ResourceListner extends FileAlterationListenerAdaptor { private final Logger log = Logger.getLogger(ResourceListner.class); private void load(File file, String event) { try { Resource.load(file.toURI().toURL()); } catch (MalformedURLException ex) { log.error(file.getName() + "is " + event + "but failed to load ", ex); } catch (ConfigurationException ex) { log.error(file.getName() + "is " + event + "but failed to load ", ex); } } @Override public void onFileChange(File file) { log.info(file.getName() + "is updated"); load(file, "updated"); } @Override public void onFileCreate(File file) { log.info(file.getName() + "is created"); load(file, "created"); } @Override public void onFileDelete(File file) { log.info(file.getName() + "is deleted"); } }
Resource
/* * To change this license header, choose License Headers in Project Properties. * To change this template file, choose Tools | Templates * and open the template in the editor. */ package sample.file.monitor.resource; import java.net.URL; import org.apache.commons.configuration.ConfigurationException; import org.apache.commons.configuration.PropertiesConfiguration; import org.apache.log4j.Logger; /** * * @author yushi.koga */ public class Resource { static private final Resource resource = new Resource(); static private final Logger log = Logger.getLogger(Resource.class); static private PropertiesConfiguration configuration; private Resource() { } public static Resource getInstance() { return resource; } public static void load(URL resourceFile) throws ConfigurationException{ try { configuration = new PropertiesConfiguration(resourceFile); } catch (ConfigurationException ex) { log.error("failde to load " + resourceFile.toString(),ex); throw new ConfigurationException(ex); } } public String getString(String key) { return configuration.getString(key); } public int getInt(String key) { return configuration.getInt(key); } public long getLong(String key) { return configuration.getLong(key); } }
WindowsとMacの両方でローカル配信メールを設定する方法
ローカルからアプリケーションがメール投げようとすると何も設定してないとエラーになっちゃいますよね。 私の職場じゃWindowsとMac使っている人が半々なのですが、どちらの環境でもこのメールの問題を解決したので書いてみます。
Windowsの場合
簡単です。 smtp4devをダウンロードして起動するだけで25ポートをlistenしてくれます。 あとはアプリがメール投げたらこの子がそれを拾ってくれるようになります。
Macの場合
Macの場合は、OSがUnix系なので、postfixを設定します。
設定をすると/Users/{username}/Maildir/
の配下にメールが届くようになります。
こんな感じ。
# command : create setting file for postfix $ sudo vi /etc/postfix/aliases.reg ## discription /(?!^root$|^{username}$)^.*$/ {username} # command : create setting file for postfix $ sudo vi /etc/postfix/transport_maps ## discription /^.*@.*$/ local # command : modify setting file for postfix $ sudo vi /etc/postfix/main.cf ## discription #local_recipient_maps = ↓ #local_recipient_maps = local_recipient_maps = #alias_maps = netinfo:/aliases ↓ #alias_maps = netinfo:/aliases alias_maps = hash:/etc/postfix/aliases,regexp:/etc/postfix/aliases.reg #home_mailbox = Mailbox ↓ #home_mailbox = Mailbox home_mailbox = Maildir/ #luser_relay = admin+$local ↓ #luser_relay = admin+$local luser_relay = {username} # add following description to bottom line transport_maps = pcre:/etc/postfix/transport_maps # command : create aliases's binaly file $ sudo postalias /etc/postfix/aliases # command : reflect $ sudo postfix reload
{username}は各自のユーザ名に置き換えてください。
postfixが起動してないとsudo postalias /etc/postfix/aliases
の箇所でエラーになります。
その場合は、sudo postfix start
してあげてください。
参考にしたサイトはこちら。
https://blog.tagbangers.co.jp/ja/2015/05/22/setting-of-local-e-mail-for-mac
CentOS7でLAMP環境構築(といいつつnginx)
友人のサイトのローカル環境を構築するのにLAMP環境をMacに入れたので、参考にしたサイトをメモ代わりに貼っておく。
CentOS 7 でLAMP(Nginx+MariaDB(MySQL)+PHP)インストールからWordPressを動かすまで(Nginx編) | レンタルサーバー・自宅サーバー設定・構築のヒント
Dockerエキスパート養成読本が出る!
今通ってる現場で、インフラ再構築ってことで今後はドッカー使うらしい。 ってことで勉強しとかないとついていけないので、電子書籍版出たらすぐ買う。
Javaでprivateメソッドをmockに置き換える方法
探していたら、mockitoでは実装してない旨のページを見つけた。
powermockでできるからそっち使ってねって書いてある(ように読める)…○r2”
社内のMさんとOさんに助けを求めたら教えてもらえたのだが、 どうやら、jmockitなるものを使えば、簡単にstaticだろうがfinalだろうがprivateだろうがmockに置き換えられる模様。 ↓教えてもらったサイト↓ qiita.com
やり方を具体例で教えてもらったが、確かに簡単かつ意図したとおりにできた!
ので、今後お世話になりそうなのでメモしておく。
以下、サンプルコード
package test.jmockit; public class JmockitSample { public static void main(String[] args){ System.out.println(new JmockitSample().methodPublic()); System.out.println(methodPublicStatic()); System.out.println(new JmockitSample().callPraivateMethod()); System.out.println(callPrivateStaticMethod()); } public String methodPublic() { return "methodPublic"; } public static String methodPublicStatic() { return "methodPublicStatic"; } public String callPraivateMethod(){ return new JmockitSample().methodPrivate(); } private String methodPrivate() { return "methodPrivate"; } public static String callPrivateStaticMethod(){ return JmockitSample.methodPrivateStatic(); } private static String methodPrivateStatic() { return "methodPrivateStatic"; } }
実行結果
methodPublic methodPublicStatic methodPrivate methodPrivateStatic
テストコード内で4つのメソッドを前もmockに置き換えて、 Mocked{メソッド名}に変更してみる
package test.jmockit; import static org.hamcrest.CoreMatchers.*; import static org.junit.Assert.*; import mockit.Mock; import mockit.MockUp; import org.junit.Test; public class JmockitSampleTest { @Test public void mockTest(){ new MockUp<JmockitSample>() { @Mock public String methodPublic() { return "mocked methodPublic"; } @Mock public String methodPublicStatic() { return "mocked methodPublicStatic"; } @Mock private String methodPrivate() { return "mocked methodPrivate"; } @Mock private String methodPrivateStatic() { return "mocked methodPrivateStatic"; } }; System.out.println(new JmockitSample().methodPublic() ); System.out.println(JmockitSample.methodPublicStatic() ); System.out.println(new JmockitSample().callPraivateMethod()); System.out.println(JmockitSample.callPrivateStaticMethod() ); assertThat(new JmockitSample().methodPublic(), is("mocked methodPublic")); assertThat(JmockitSample.methodPublicStatic(), is("mocked methodPublicStatic")); assertThat(new JmockitSample().callPraivateMethod(), is("mocked methodPrivate")); assertThat(JmockitSample.callPrivateStaticMethod(), is("mocked methodPrivateStatic")); } }
結果
mocked methodPublic mocked methodPublicStatic mocked methodPrivate mocked methodPrivateStatic
注意点
クラスパスがjunitよりも先に来てないとうまく動かないので、その点だけ注意して下さい。 Eclipseだとこんな感じにすればOK
gradleならこんな感じ
apply plugin: 'java' apply plugin: 'eclipse' sourceCompatibility = '1.7' [compileJava, compileTestJava]*.options*.encoding = 'UTF-8' configurations { jmockit_agent } repositories { mavenCentral() } dependencies { jmockit_agent 'com.googlecode.jmockit:jmockit:1.7' testCompile 'com.googlecode.jmockit:jmockit:1.7' testCompile 'junit:junit:4.11' } test { jvmArgs "-javaagent:${configurations.jmockit_agent.asPath}" }
ちなみにNetBeansの場合は、gradle使ってる場合はgradleに完全にコンパイル任せてるのでbulid.gradleの設定さえしておけば、うまく動きます。
参考にしたサイトその1 knjname.hateblo.jp
参考にしたサイトその2 gist.github.com