第三场阴影场与属性访问器接口

这是“ 影子字段属性访问器”界面的 第3轮 。 如果您是新手,但不确定要怎么做,请查看我以前的文章或关于开发JavaFX应用程序时节省内存的第一篇文章 。 作为Java开发人员,我主要关心的是在开发JavaFX域模型时在性能内存使用和降低样板代码(易于使用API​​)之间取得良好的平衡。 通常,应用程序框架提供模型视图控制器(MVC)或表示模型模式以将UI代码与域对象分开。 实际上,想到的是域模型类型对象应该易于创建或生成( IDE )。 在此博客条目中,您将看到第3轮的结果,其中包括两个部分 。 第1部分是使用Marcel Heckel的想法实施的,第2部分是我最终根据性能内存使用易用性实现的一种实现。

  • 免责声明:使用任何代码均需自担风险。 这纯粹是实验性的,不应在生产中使用。 这是一个进展中的工作。

最新的代码在这里—> [ PropertyAccessors接口 ]

第二轮回顾

尽管上一轮( 第2轮 )表明我的Property Accessors策略在内存消耗方面比标准(fat)特性对象策略稍微好一点,但是当创建2,000,000个具有本地类型的Employee类型类的对象时,它在性能方面仍然令人失望输入对象 。 与Dirk的实现相比,我对第二轮实现的内存使用仍然不满意。 如果您只关心我在第3轮中的最终成绩,请跳至“ 结果”部分。

因为,可能会有新的回合,如果您决定使用它,或者假设Dirk决定在此处接受我的拉取请求,请转到此处查看当前代码。

在第2轮中,我使用了一个哈希映射查找,因为随着O(1)时间复杂度(搜索)越来越多地添加了越来越多的字段,它的查找速度可能会非常慢。 有趣的是,Marcel Heckel提出了一种创建对象索引数组的简单方法,该方法不仅可以节省更多内存,而且速度更快。 与键/值对查找相比,直接访问字段绝对是必经之路。 尽管Marcel的代码速度更快,但它仍然比Dirk的Shadow Fields代码占用更多的内存。 额外的内存实际上是通过预分配一个数组来占用的,该数组将保存每个字段的值。 即使它们全为 ,也会为每个员工对象创建数组本身。 我在这里实施了Marcel的策略(第23行)。 让我们看一下索引字段数组策略的结果。

第1部分:使用索引字段数组

private final Object[] modelProperties =new Object[FIELDS.values().length];public Object[] getModelProperties(){return modelProperties;}

测试:对象不使用属性字段

下面显示的是混合使用Marcel的索引数组思想和我使用枚举类型指定属性名称以将字段表示为属性字段的方式。

screen-shot-2016-04-07-at-12-18-01-am

与所有字段均作为JavaFX属性的标准(胖)对象相比,未使用JavaFX属性的对象。 此实现对每个字段使用数组索引,并使用数组保存每个值。

在上方,您会注意到未选中该复选框,以指示不要在域对象上创建JavaFX 属性不使用xxxxProperty()方法 )。 您会注意到,与第二回合的代码相比,性能得到了显着提高,并且内存使用量也减少了。 在上图中, Property Accessor界面Shadow Fields的模式实现多了16MB 。 在瘦对象​​性能和内存使用的第1部分中, Shadow Fields是明显的赢家。 但是,Shadow Fields仍然不太干净。 还要注意的另一件事是,对于200万个对象,Property Accessors接口仅不到14毫秒! 正如我们将在第2部分稍后将带回专用实例变量作为字段所看到的那样 ,Property Accessors界面将真正随着内存使用而发光。

测试:对象使用属性字段

以下是对象的所有字段都使用JavaFX属性时的结果。

screen-shot-2016-04-07-at-12-24-22-am

使用JavaFX属性的对象与标准(胖)对象相比,所有字段均作为Javafx属性。 此实现对每个字段使用数组索引,并使用数组保存每个值。

在这里,您会注意到200万个对象的Accessor列(Property Accessors接口)在916毫秒内执行,使用了576 MB的内存。 在这种情况下,就544 MB的内存空间而言,标准(胖)对象是获胜者。 到目前为止,Shadow Fields在每一轮比赛中都表现出色。

Marcel的代码示例 (在注释部分)的一个小细节是,在创建新的属性对象实例时,它没有考虑属性的字符串名称 。 例如,以下语句显示变量totalProperty ,其属性名为“ total ”,该属性与totalProperty()方法匹配。 在更改过程中触发属性名称对于读取代码,测试和工具很重要。

属性totalProperty = new SimpleIntegerProperty(this,“ total”,new Integer(5));

为了同时拥有一个命名字段和一个类似于Marcel的想法的索引,我只创建了一个枚举来声明每个字段的属性。 这些枚举在Employee类上创建。

// Part 1 implementation
public class EmployeePropertyAccessor implements PropertyAccessors{public enum FIELDS {name,powers,supervisor,minions}private final Object[] modelProperties =new Object[FIELDS.values().length];public Object[] getModelProperties(){return modelProperties;}// The rest of the code...

在上面,您会注意到将如何基于已定义字段(枚举FIELDS)的数量创建模型Properties数组。 我使用FIELDS.value()。length定义数组的大小。 另外, PropertyAccessors接口( 第1部分的实现 )强制开发人员实现getModelProperties()方法。 在这里,我只是返回对对象数组的modelProperties引用。 “ 必须 ”实现一个数组和一个getModelProperties()方法并不是一件很愉快的事情

在本文的第2部分中,我以不同的方式实现了一些事情,其中​​开发人员没有被迫实现modelProperties数组和getModelProperties()方法。 我将解决此问题,使代码看起来更简洁,性能更好(API观点的用户)。

第2部分:重新引入实例变量

在第2部分中,我将把私有实例变量重新添加到Employee类( EmployeePropertyAccessor )中,以保存字段值,而不是像第1部分中那样包含数组。我的想法是使字段变量与指向本机对象的任一点互斥类型或JavaFX属性,从而与“影子字段”模式代码相比节省了内存。 由于“ 阴影字段”代码使用两个变量来表示字段值,因此它将具有一个额外的引用,当对象使用属性时,该引用将不可避免地增加其内存。 正如您在下面看到的那样,该代码看起来与第1部分相似,但也将具有一个静态块以在类中注册属性字段。 这很重要,因为您可能不希望某些实例变量作为JavaFX属性参与。

// Part 2 implementation
public class EmployeePropertyAccessor implements PropertyAccessors {private Object name;private Object powers;private Object supervisor;private Object minions;enum FIELDS {name,powers,supervisor,minions}static {// register fields one time.// (Warning: enum's ordinal value is reassigned an index number)registerFields(EmployeePropertyAccessor.class, FIELDS.values());}public EmployeePropertyAccessor(String name, String powers) {setName(name);setPowers(powers);}public final String getName() {return getValue(FIELDS.name, "");}public final void setName(String name) {setValue(FIELDS.name, name);}public final StringProperty nameProperty() {return refProperty(FIELDS.name,
SimpleStringProperty.class, String.class);}// The rest of the code...

上面的代码清单在调用registerFields()方法时做了一些有趣的魔术 。 使用反射重新分配 FIELDS枚举的序数值,从而为每个枚举赋予一个新的id作为数组的索引。 这提供了不可变的枚举,同时还包含要通过索引快速访问的每个字段的唯一标识符。 由于枚举用于表示要用作属性的字段,因此序数值在其他上下文中没有意义。 这意味着:谁在乎,是否在这些声明的枚举上重新分配了序数值? 它们仅用于“ 注册字段 ”。

测试:对象不使用属性字段[NEW]

下面显示的是使用Property Accessors接口API的新实现的测试结果。 下面的测试显示了与标准胖对象相比,何时不使用属性字段。

将标准对象(使用属性的所有字段)与使用本机对象的对象进行比较的测试。现在,Property Accessors接口API使用实例变量作为字段,而不是对数组的引用。

将标准对象(使用属性的所有字段)与使用本机对象的对象进行比较的测试。 现在,Property Accessors接口API使用实例变量作为字段,而不是对数组的引用。

正如您在上面看到的那样,Property Accessors接口的新实现显然是内存使用率和易用性的赢家。 性能比第1部分的实现稍慢,但是节省内存是值得的。 您会注意到,“影子字段”的内存使用量比“属性访问器”的使用量多16 MB。

测试:对象使用属性字段[NEW]

下面显示的是使用Property Accessors接口API的新实现的测试结果。 下面的测试显示与标准脂肪对象相比,何时使用属性字段。 (在“开始”按钮下方选中了该复选框)

screen-shot-2016-04-09-at-12-36-02-pm

第三回合的结果

以下是我根据表格中的结果汇总在一起的条形图。 我觉得人们喜欢看图表而不是表格,单元格和文本。

performance_a

对象不使用JavaFX属性时的性能测试结果。 较小的数字(以毫秒为单位)更好。

performance_b

对象使用JavaFX属性时的性能测试结果。 较小的数字(以毫秒为单位)更好。

memusage_a

对象不使用JavaFX属性时的内存使用情况测试结果。 较小的数字(以兆字节为单位)更好。

memusage_b

对象使用JavaFX属性时的内存使用情况测试结果。 较小的数字(以兆字节为单位)更好。

结论

根据结果​​,我的目标是明确实现的 (IMHO),我最初希望代码在对象可能使用或不使用JavaFX属性时都易于阅读并且易于实现( 当字段不使用JavaFX时还可以节省内存)属性[本机类型] )。 尽管在所有测试运行中都赢得了性能方面的Shadow Fields的认可,但Property Accessors界面并没有落后。 当不使用属性时,在创建200万条记录时,Property Accessors界面仅比标准对象策略短5毫秒。

对于创建200万个对象的内存使用情况,以及当策略未使用属性作为字段时, Property Accessors界面显然是赢家,与Shadow Fields模式相比至少节省16MB ,与Shadow Fields模式相比节省240MB。标准属性代码。 最后,但并非最不重要的是,当对象将属性用作字段时,Property Accessors接口与有关内存消耗的Standard对象策略相关联。 Shadow Fields策略使用的内存至少比其他策略多20MB。

尽管在使用不使用所有字段作为200万个对象的属性时,Properties Accessors接口会稍慢一些(以毫秒为单位的微小差异),但我相信该API可以在任何JavaFX应用程序大小上使用,以简化域的开发模型和对象。 我鼓励其他人在决定使用API​​之前先测试代码。 请注意,该代码不适合生产,并且处于试验阶段。 这是一项正在进行中的工作,因此,在我开始吃自己的狗食(工作时)之前,我真的不建议您使用Property Accessors API。 我将在下面重申免责声明:

  • 免责声明:使用任何代码均需自担风险。 这纯粹是实验性的,不应在生产中使用。 这是一个进展中的工作。

随时发表评论和订阅。 祝您编程愉快!

翻译自: https://www.javacodegeeks.com/2016/04/shadow-fields-vs-property-accessors-interface-round-3.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/354351.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

移动端布局三种视口_前端基础:必须要知道的移动端适配(4)——视口

视口(viewport)代表当前可见的计算机图形区域。在Web浏览器术语中,通常与浏览器窗口相同,但不包括浏览器的UI, 菜单栏等——即指你正在浏览的文档的那一部分。一般我们所说的视口共包括三种:布局视口、视觉视口和理想视口&#xf…

js判断移动端,pc端,安卓,苹果浏览器的方法

js 判断安卓或者ios 之indexOf方式(一) //判断访问终端 var browser{versions:function(){var u navigator.userAgent, app navigator.appVersion;return {trident: u.indexOf(Trident) > -1, //IE内核presto: u.indexOf(Presto) > -1, //opera…

Vue路由开启keep-alive缓存页面

mode:hash模式下&#xff1a; HTML部分&#xff1a; <template><div id"app"><keep-alive> <!--使用keep-alive会将页面缓存--><router-view v-if"$route.meta.keepAlive"></router-view></keep-alive> &l…

平安性格测试题及答案_面试要求做性格测试,该怎么做?

为了筛选到更符合岗位&#xff0c;许多企业在招聘时都选择了“性格测试”。比如&#xff0c;像“华为、宝洁、阿里”等这样的大厂&#xff0c;据说每年都有不少人因为性格测试而凉凉&#xff0c;性格测试真有决定你“生死”的作用吗&#xff1f;那么&#xff0c;在做测试题的时…

CSS行内元素和块级元素的水平居中,垂直居中,水平垂直居中实现

常用内联元素&#xff1a;a,img,input,lable,select,span,textarea,font 常用的块级元素&#xff1a;div,p,table,form,h1,h2,h3,h4,h5,h6,dl,ol,ul,li 一、水平居中 行内元素居中&#xff1a; text-align:center 图片&#xff0c;单个块级元素居中&#xff1a;margin-left和…

mysql scrapy 重复数据_大数据python(scrapy)爬虫爬取招聘网站数据并存入mysql后分析...

基于Scrapy的爬虫爬取腾讯招聘网站岗位数据视频(见本头条号视频)根据TIOBE语言排行榜更新的最新程序语言使用排行榜显示&#xff0c;python位居第三&#xff0c;同比增加2.39%&#xff0c;为什么会越来越火&#xff0c;越来越受欢迎呢&#xff0c;背后折射出的是人工智能、机器…

vim 文本一些行注释,替换

按键操作&#xff1a;注释&#xff1a;ctrlv 进入列编辑模式,向下或向上移动光标,把需要注释的行的开头标记起来,然后按大写的I,再插入注释符,比如"#",再按Esc,就会全部注释了。删除&#xff1a;先按v,进入visual模式,横向选中列的个数(如"#"注释符号,需要…

如何在几分钟内安装Red Hat Container Development Kit(CDK)

作为负责开发容器化应用程序提供的可能性的应用程序开发人员或架构师&#xff0c;将所有工具集中在一起以使您入门时几乎没有帮助。 到现在。 红帽容器开发套件&#xff08;CDK&#xff09; 安装变得简单&#xff01; 红帽提供了一个容器开发套件&#xff08;CDK&#xff0…

vue的使用(引用/创建vue项目)(一)

在程序开发中&#xff0c;有三种方式创建vue项目&#xff0c;本地引入vuejs、使用cdn引入vuejs、使用vue-cli创建vue项目。其中vue-cli可以结合webpack打包工具使用&#xff0c;大大方便了开发步骤&#xff0c;使用广泛。 一、vue本地引用 在官网下载vue.js&#xff0c;通过s…

你不知道的JS5-原型

1、原型 [[prototype]] js中的对象有一个特殊的[[prototype]]内置属性&#xff0c;其实就是对于其他对象的引用&#xff0c;几乎所有的对象在创建时[[prototype]]属性都会被赋予一个非空的值 使用for..in和in操作符都会查找对象的整条原型链 所有普通的[[prototype]]链最终都会…

enum 定义3个属性_和平精英:合金龙骨有3个隐藏属性,比玛莎“水下无敌”还唬人...

欢迎诸位小伙伴们来到天哥开讲的《和平精英》“精英那点事儿”~接下来呢&#xff0c;咱们聊聊合金龙骨的3个隐藏属性、土豪玩家“自投罗网”以及游戏里的“公主病患者”等有趣的玩家游戏经历与发现~得&#xff0c;废话不多说了&#xff0c;还是各位小伙伴们熟悉的“老配方”&am…

vue-cli项目引用文件/组件/库 的注意事项(一)

vue引入的问题 &#xff08;1&#xff09;main.js入口文件引入(项目中所有的页面都会加载main.js&#xff0c;所以用户放全局变量) // Element import ElementUI from ‘element-ui’ import ‘element-ui/lib/theme-chalk/index.css’ Vue.use(ElementUI) &#xff08;2&am…

java中缓冲区和缓存_Java中的Google协议缓冲区

java中缓冲区和缓存总览 协议缓冲区是一种用于结构化数据的开源编码机制。 它是由Google开发的&#xff0c;旨在实现语言/平台中立且可扩展。 在本文中&#xff0c;我的目的是介绍Java平台上下文中协议缓冲区的基本用法。 Protobuff比XML更快&#xff0c;更简单&#xff0c;并…

三十七 Python分布式爬虫打造搜索引擎Scrapy精讲—将bloomfilter(布隆过滤器)集成到scrapy-redis中...

Python分布式爬虫打造搜索引擎Scrapy精讲—将bloomfilter(布隆过滤器)集成到scrapy-redis中&#xff0c;判断URL是否重复 布隆过滤器(Bloom Filter)详解 基本概念 如果想判断一个元素是不是在一个集合里&#xff0c;一般想到的是将所有元素保存起来&#xff0c;然后通过比较确定…

绩效管理的实际案例:2024年绩效提升重要方法

案例一&#xff1a;目标设定与衡量的艺术 背景&#xff1a;某科技公司每年都会为其全球员工设定年度目标。然而&#xff0c;这些目标往往过于模糊&#xff0c;导致员工不清楚自己需要完成什么。 问题&#xff1a;目标设定不清晰&#xff0c;导致员工感到困惑和不满。 解决方…

array python 交集_模糊数学Python库简介和评测

写在前面模糊数学是国内外许多工学、管理学研究生以上的选修甚至必修课程。但对于非数学专业而言&#xff0c;掌握模糊数学的各种计算方法、了解各种方法的用途&#xff08;应用场景&#xff09;其实要比理解模糊数学的“数学”理论要重要得多。目前在Matlab等数学工具中其实也…

使用Hibernate和Spring设置分布式Infinispan缓存

一个非常典型的设置–需要分布式缓存的spring / hibernate应用程序。 但是事实证明&#xff0c;设置并不是那么简单。 您显然需要缓存。 可以使用EhCache&#xff0c;Hazelcast&#xff0c;Infinispan&#xff0c;memcached&#xff0c;Redis&#xff0c;AWS的Elasticache以及…

Element UI 的使用

官方文档&#xff1a; https://element.eleme.io/#/zh-CN/component/installation 一、普通项目引入相关文件&#xff0c;使用elementui插件&#xff1a; &#xff08;1&#xff09;引入相关文件 &#xff08;2&#xff09;可以直接使用了 vue项目使用elementui 安装 &…

python基础十一之迭代器和生成器

可迭代 内置方法中含有__iter__的数据类型都是可迭代的&#xff0c;只要是可迭代的就可以使用for循环&#xff0c;反之亦然。 print(dir()) # dir()函数可以获取当前数据类型的所有内置方法 返回值是list print(__iter__ in dir([])) # 判断是否含有__iter__内置方法 迭代器…

架构设计器_大厂案例:马蜂窝大交通业务监控报警系统架构设计与实现

部门的业务线越来越多&#xff0c;任何一个线上运行的应用&#xff0c;都可能因为各种各样的原因出现问题&#xff1a;比如业务层面&#xff0c;订单量比上周减少了&#xff0c;流量突然下降了&#xff1b;技术层面的问题&#xff0c;系统出现 ERROR &#xff0c;接口响应变慢了…