网站搜索出来有图片,一个网站开发背景是什么,企业邮箱注册域名是什么,wordpress搜索乱码转载自 性能优化之抛弃Calendar
目前在做限流相关的需求#xff0c;有这么一个限流策略#xff0c;和用户相关#xff0c;当系统发生故障时#xff0c;允许一个非核心接口按照用户的百分比进行限流#xff0c;如果完全按照UUID进行hash#xff0c;那么每次都是限制同一…转载自 性能优化之抛弃Calendar
目前在做限流相关的需求有这么一个限流策略和用户相关当系统发生故障时允许一个非核心接口按照用户的百分比进行限流如果完全按照UUID进行hash那么每次都是限制同一批的用户如果在UUID的基础上加上当天的日期那么就可以有效的避免这个问题。
所以在这个需求中每次请求都需要拿到当前的日期不过精确到天即可。 嗖~的一下完成了如下代码
Calendar calendar Calendar.getInstance();
String time calendar.get(Calendar.YEAR) calendar.get(Calendar.MONTH) calendar.get(Calendar.DAY_OF_MONTH);
很简单是不是不过写完之后很快就被业务同学diss了Calendar性能太差了在QPS很高的情况下会使接口的999线劣化。 QPS高的业务真是惹不起... 丢
为什么Calendar不行因为每次请求都要创建一个Calendar实例这个创建过程比较的耗时qps低的时候可以忽略这种消耗但是做基础组件的应该考虑各种场景。
因为只需要获取到与天相关数据所以想到了另一个简单的解决方案
private static final int DAY_MILLIS 24 * 60 * 60 * 1000;
long day System.currentTimeMillis() / DAY_MILLIS;
通过当前的时间戳毫秒级别除以一天的毫秒数得到的结果就是从1970 到今天经历过的天数这完全符合当前的需求。
这个解决方案只是恰好可以满足这种需求对于其它更复杂一点的需求我这里推荐使用 JodaTime组件。
下面通过Openjdk的JMH类库对上述三种情况进行性能基准测试还没有接触过JMH的同学可以在官网上进行学习传送门
OutputTimeUnit(TimeUnit.NANOSECONDS)
BenchmarkMode(Mode.AverageTime)
public class Main {static int millis 24 * 3600 * 1000;public static void main(String[] args) throws Exception {Options options new OptionsBuilder().include(Main.class.getName()).forks(1).build();new Runner(options).run();}BenchmarkThreads(5)public void runCalendar() {Calendar calendar Calendar.getInstance();}BenchmarkThreads(5)public void runJoda() {DateTime dateTime new DateTime();}//BenchmarkThreads(5)public void runSystem() {long result System.currentTimeMillis() / millis;}}
使用benchmark之前需要引入相关依赖
dependencygroupIdorg.openjdk.jmh/groupIdartifactIdjmh-core/artifactIdversion1.21/version
/dependency
dependencygroupIdorg.openjdk.jmh/groupIdartifactIdjmh-generator-annprocess/artifactIdversion1.21/versionscopeprovided/scope
/dependency 最终结果如下
这里只是测试了Calendar和Joda对象的创建耗时可以发现Joda的性能比Calendar整整高了10倍真的不可忽略。