游戏开发中,通常使用"n段式"代表道具和货币,也经常要把字符串转成Uniparam对象。
系统一定会频繁地生成UniParam对象,所以加入了WeakHashMap作为缓存,还对比了一下性能的差异。
/**
* 统一变参参数配置格式
*
* 定义ID : 参数1 & 参数2 & 参数3 & ...
*
* 定义ID : [10,20] & [测试1,测试2] & 参数3 //表示值在 10,20中随机一个
*
* 定义ID : [10~20] & [0.01~1.00]
* //表示参数1在10到20中随机一个整数,参数2在0.01~1.00随机一个Double(最多小数点后两位)
*
* 嵌套用{} 2003:1&{2003:1&2&3}&3
*
*
* 约定,一般多个UniStrParam用分号(;)隔开 例如, 10056001;10056002;1:1.04&3&测试;2:333&509&测试
*
*
*/
public class UniStrParamFaster {
private List<String> arrayList;
public List<String> getArrayList() {
......
}
// 用于序列化
public UniStrParamFaster() {
}
public UniStrParamFaster(String strUnit) {
......
}
public int GetParamSize() {
return arrayList.size() - 1;
}
public int GetDefineID() {
......
}
public int GetIntParam(int index) {
.......
}
public String GetStrParam(int index) {
......
}
public double GetDoubleParam(int index) {
.......
}
public UniStrParamFaster getUniStrParam(int index) {
.......
}
/**
* 修改第pos个参数为value值
*
* @param pos
* @param value
* @return
*/
public void modify(int pos, double value) {
.......
}
/**
* 修改第pos个参数为value值
*
* @param pos
* @param value
* @return
*/
public void modify(int pos, int value) {
.......
}
/**
* 修改第pos个参数为value值
*
* @param pos
* @param value
*/
public void modify(int pos, String value) {
......
}
public String toString() {
......
}
public String toUniString() {
......
}
//测试性能
private static Map<String, UniStrParamFaster> weakCacheMap = new WeakHashMap<>();
private static Map<String, UniStrParamFaster> lruCacheMap = new LruCacheMap<>();
private static AtomicInteger factor = new AtomicInteger(0);
public static String getTestStr() {
StringBuilder str = new StringBuilder().append(factor.getAndIncrement())
.append(":").append(factor.getAndIncrement())
.append("&").append(factor.getAndIncrement())
.append("&").append(factor.getAndIncrement());
return str.toString();
}
public static UniStrParamFaster getParamFromWeakMap(String paramStr) {
UniStrParamFaster paramData = weakCacheMap.get(paramStr);
if (paramData == null) {
paramData = new UniStrParamFaster(paramStr);
weakCacheMap.put(paramStr, paramData);
}
return paramData;
}
public static UniStrParamFaster getParamFromLruMap(String paramStr) {
UniStrParamFaster paramData = lruCacheMap.get(paramStr);
if (paramData == null) {
paramData = new UniStrParamFaster(paramStr);
lruCacheMap.put(paramStr, paramData);
}
return paramData;
}
private final static ExecutorService executorService = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());
private static List<String> prepareData() {
int a = 10000;
int b = 1000;
CountDownLatch countDownLatch = new CountDownLatch(a * b);
List<String> data = Collections.synchronizedList(new ArrayList<>(800000));
for (int i = 0; i < a; i++) {
String d = getTestStr();
executorService.execute(() -> {
for (int j = 0; j < b; j++) {
data.add(d);
countDownLatch.countDown();
}
});
}
try {
countDownLatch.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
Collections.shuffle(data);
return data;
}
private static void test1() {
List<String> data = prepareData();
/Round1
long startTime = System.currentTimeMillis();
for (int i = 0; i < data.size(); i++) {
final String d = data.get(i);
new UniStrParamFaster(d);
}
System.out.println("new->" + (System.currentTimeMillis() - startTime));
/Round2
startTime = System.currentTimeMillis();
for (int i = 0; i < data.size(); i++) {
final String d = data.get(i);
getParamFromWeakMap(d);
}
System.out.println("weakMap->" + (System.currentTimeMillis() - startTime));
/Round3
startTime = System.currentTimeMillis();
for (int i = 0; i < data.size(); i++) {
final String d = data.get(i);
getParamFromLruMap(d);
}
System.out.println("lruCacheMap->" + (System.currentTimeMillis() - startTime));
executorService.shutdown();
}
@SuppressWarnings("unused")
private static void test2() {
List<String> data = prepareData();
long startTime = System.currentTimeMillis();
for (int i = 0; i < data.size(); i++) {
String d = data.get(i);
getParamFromWeakMap(d);
}
System.out.println(System.currentTimeMillis() - startTime);
System.gc();
startTime = System.currentTimeMillis();
for (int i = 0; i < data.size(); i++) {
String d = data.get(i);
getParamFromLruMap(d);
}
System.out.println(System.currentTimeMillis() - startTime);
}
@SuppressWarnings("unused")
private static void test3() {
List<String> data = prepareData();
for (int i = 0; i < 31; i++) {
if ((1 << i) > data.size()) {
break;
}
LruCacheMap.setMAX_ENTRIES(1 << i);
lruCacheMap.clear();
long startTime = System.currentTimeMillis();
for (int j = 0; j < data.size(); j++) {
String d = data.get(j);
getParamFromLruMap(d);
}
System.out.println("cache size:" + LruCacheMap.getMAX_ENTRIES() + "->" + (System.currentTimeMillis() - startTime));
}
}
public static void main(String[] args) {
test1();
//test2();
//test3();
}
}
获取10000000次UniParam的结果如图:
LruCacheMap为什么这么快,因为使用了最近最少使用的策略,并且限制了元素的个数:
public class LruCacheMap<K, V> extends LinkedHashMap<K, V> {
private static final long serialVersionUID = 6918023506928428613L;
private static int MAX_ENTRIES = 10000;
/**
* 获得允许存放的最大容量
*
* @return int
*/
public static int getMAX_ENTRIES() {
return MAX_ENTRIES;
}
/**
* 设置允许存放的最大容量
*
* @param int max_entries
*/
public static void setMAX_ENTRIES(int max_entries) {
MAX_ENTRIES = max_entries;
}
/**
* 如果Map的尺寸大于设定的最大长度,返回true,再新加入对象时删除最老的对象
*
* @param Map.Entry eldest
* @return int
*/
protected boolean removeEldestEntry(Map.Entry<K, V> eldest) {
return size() > MAX_ENTRIES;
}
public static void main(String[] args) {
Map<Integer, Boolean> map = new LruCacheMap<Integer, Boolean>();
LruCacheMap.setMAX_ENTRIES(10);
System.out.println(map.size());
for (int i = 0; i < 50; i++) {
map.put(i, true);
System.out.println(map.size());
System.out.println(map);
}
}
}
break-word会对过长的单词做词内断词处理,这样单词始终会在容器中,不会溢出容器break-all很暴力的一种处理方法,过长单词先断词处理,占满一行,然后再换行处理每次看到这两个css属性都是一种眼晕的感觉,今天就来总结一下。首先我们来来分别介绍一下这两个属性有哪些值:word-break:值描述break-all允许单词内换行keep-all&nb..._word-break keep all不兼容
代码未经测试,只是偶尔看到,做个备份,ffmpeg也自带有转音频声道的extern "C" {#include #include #include }// 这里是PortAudio的头文件#include #include #include struct AudioContext { AVCodecContext* code_音频重采样 与 双耳合成立体声 csdn
X11,GTK,QT,GNOME的区别与联系X11是X Window System Protocol, Version 11(RFC1013),是X server和Xclient之间的通信协议。X server是xfree86/xorg驱动下的显示设备鼠标键盘统称,Xclient通过X11协议和xfree86/xorg实现的Xserver通信,比如,告诉它画一个左上角坐标为(x_xorg clients与server失联
1、insert插入一条记录: 2、insert插入多条记录: 3、update指定条件更新记录: 4、delete指定条件删除记录:delete * from person where id=25、delete删除所有记录:delete from person6、select查询表中所有数据:select * from person7、select指定条件查询:select * from p
记录以下今天刷力扣发现的Python语法小知识:列表插入1. insert()函数a=[1,2,3]a.insert(1,[4,5])#第一个参数表示插入位置的索引,第二个参数为插入内容print(a)#[1, [4, 5], 2, 3]#insert 操作支持插入整数、列表等多种数据类型2. 列表切片a=[1,2,3]a[1:1]=[4,5]print(a)#[1, 4, 5, 2, 3]如果想在某个位置批量插入某些元素,可以直接把要插入的元素打包成一个可迭代对象使用list[_python列表插入
本文版权归ljh2000和博客园共有,欢迎转载,但须保留此声明,并给出原文链接,谢谢合作。本文作者:ljh2000作者博客:http://www.cnblogs.com/ljh2000-jump/转载请注明出处,侵权必究,保留最终解释权!Problem Description 人随着岁数的增长是越大越聪明还是越大越笨,这是一个值得全世界科...
提交代码git add xxxxgit commit -m ""git push冲突解决git add xxx <如果这一步操作报错>git stashgit pullgit stash pop误提交代码git reset HEAD -- 将file退回到unstage区...
Visual Studio Professional 2015简体中文版(专业版)KEY:HMGNV-WCYXV-X7G9W-YCX63-B98R2Visual Studio Enterprise 2015简体中文版(企业版)KEY:HM6NR-QXX7C-DFW2Y-8B82K-WTYJV
leetcode的几道链表练习题:package com.freshbin.basics.linkedlist;/** * @author freshbin * @date 2020/5/2 14:54 */public class ListNode { int val; ListNode next; ListNode(int x) { ..._int middle = (start +end )/2 ;if(start>=end)
工具准备:工具:VS2017环境:.Net Core 2.0 ,EF7这里因为刚学习,自己遇到的坑:Powershell2.0升级3.0问题,下载安装包安装完成后重新电脑就好了。https://www.microsoft.com/zh-CN/download/details.aspx?id=40855 1,我们需要的是建一个解决方案,一个类库项目,以及一个Web项目..._.net core建站
It is well known that AekdyCoin is good at string problems as well as number theory problems. When given a string s, we can write down all the non-empty prefixes of this string. For example: s: "ab...
**小小目录**传统艺能????过渡区????正片开始字符串????转义字符????传统艺能????小编是大一菜鸟不赘述,欢迎大佬指点江山(QQ:1319365055)此前博客点我!点我!请搜索博主 【知晓天空之蓝】或扫码进入!(https://blog.51cto.com)感谢支持!过渡区????现在是北京时间8:06,去操场小跑一下完了硬是被破防整感冒了,得亏上午一二节无课,卷完博客真的就要躺平咯。正片开始字符串????刚看到字符串时,我的第一印象就是一串字符,结果证明我是_7-2 乔乔的交友标准 (10 分)c语言