精通安卓性能优化-第一章(九)

Android开发初期之后怎么提升?怎么才能叫精通?方向在哪? 1. Android开发初期之后怎么提升? 首先第一个问题:Android开发初期之后怎么提升?说到这个问题,就不得不先搞清楚 “为什么很多人会一直停留在两三年的水平上,而后一直在重复以往的经验,原地踏步?” 我认为最主要的一个原因就是这部分开发者缺乏主观能动性,或者说缺乏能支撑你坚持学习的兴趣。如果你对Android开发没有太大的兴趣,那么还是尽早换方向吧。有了兴趣,然后就是要有一个比较正确的钻研路线,不要这也搞那也抓,最后什么都知道点,但也就只是知道点儿。 一个很好的例子就是我们平时在开发过程中都会用 阅读详情

SQLite

很多应用程序不是SQLite的重度使用者,因此非常幸运的不需要去担心太多处理数据库的性能问题。然而,如果需要去优化Android应用中SQLite相关的代码的情况下需要知道几个概念:
(1) SQLite状态
(2) 事务(Transaction)
(3) 查询

NOTE:本节不打算成为SQLite的完整指南,而是提供给你几个点去保证有效的使用数据库。完整的指南,参考www.sqlite.org和Android在线文档。

本节所涉及到的优化不会使得代码更加难以阅读和维护,所以需要养成使用它们的习惯。

SQLite Statements

开始的时候,SQL 语句是简单的字符串,比如:
(1) CRTEATE TABLE cheese (name TEXT, origin TEXT)
(2) INSERT INTO cheese VALUES(‘Roquefort’, ‘Roquefort-sur-Soulzon’)

第一条语句创建一个名字为cheese,包含两列名字分别为name和origin的表。第二行将在表中插入新的一行。因为它们是简单的字符串,语句在执行前需要被解释或者编译。当你调用比如SQLiteDatabase.execSQL的时候,这些语句的编译在内部执行,如Listing 1-18所示。

Listing 1-18 执行简单的SQLite语句

SQLiteDatabase db = SQLiteDatabase.create(null);    // memory-backed database
db.execSQL("CREATE TABLE cheese (name TEXT, origin TEXT)");
db.execSQL("INSERT INTO cheese VALUES ('Roquefort', 'Roquefort-sur-Soulzon')");
db.close();    // 记得关闭数据库

NOTE:许多SQLite相关的方法会抛异常。

事实证明,执行SQLite语句需要相当一段时间。除了编译,语句本身可能需要被创建。因为String是不可变的,这可能导致和在computeRecursivelyFasterUsingBigInteger()使用大数字BigInteger同样的性能问题。我们现在聚焦于插入语句的性能问题,毕竟,一个表可能仅被创建一次,但是许多行可能会添加、修改或者删除。
如果我们要建立cheeses的一个全面的数据库,我们可能会以许多插入语句结束,如Listing 1-19所示。对每一个插入语句,一个String将被创建,另外execSQL将被调用,每个cheese添加到数据库的时候,都会在内部解析SQL语句。

Listing 1-19 创建一个全面的Cheeses数据库

public class Cheeses {
    private static final String[] sCheeseNames = {
        "Abbaye de Belloc",
        "Abbaye du Mont des Cats",
        ...
        "Vieus Boulogne"
    };
    
    private static final String[] sCheeseOrigins = {
        "Notre-Dame de Belloc",
        "Mont des Cats",
        ...
        "Boulogne-sur-Mer"
    };
    
    private final SQLiteDatabase db;
    public Cheeses() {
        db = SQLiteDatabase.create(null);    // memory-backed database
        db.execSQL("CREATE TABLE cheese (name TEXT, origin TEXT)");
    }
    
    public void populateWithStringPlus() {
        int i = 0;
        for(String name:sCheeseNames) {
            String origin = sCheeseOrigins[i++];
            String sql = "INSERT INTO cheese VALUES(\"" + name + "\",\"" + origin + "\")";
            db.execSQL(sql);
        }
    }
}

在Galaxy Tab 10.1,添加650个cheese到memory-backed的数据库需要393毫秒或者每行需要0.6毫秒。


一个明显的改进是使得sql语句的创建更快。在这种情况下,通过+操作符去连接字符串不是最有效的方法,通过StringBuilder或者调用String.format去改善性能是可能的。这两个新的方法展示在Listing 1-20中。它们只是优化了传给execSQL的字符串的创建方式,这两个优化不是SQL相关的。

Listing 1-20 创建SQL语句字符串更快的方式

public void populateWithStringFormat() {
    int i=0;
    for (String name : sCheeseNames) {
        String origin = sCheeseOrigins[i++];
        String sql = String.format("INSERT INTO cheese VALUES(\"%s\", \"%s\")", name, origin);
        db.execSQL(sql);
    }
}

public void populateWithStringBuilder() {
    StringBuilder builder = new StringBuilder();
    builder.append("INSERT INTO cheese VALUES(\"");
    int resetLength = builder.length();
    int i=0;
    for(String name : sCheeseNames) {
        String origin = sCheeseOrigins[i++];
        builder.setLength(resetLength);    // 重设位置
        builder.append(name).append("\", \"").append(origin).append("\")");    // chain calls
        db.execSQL(builder.toString());
    }
}

添加同样数量的cheese,String.format版本需要436毫秒,而StringBuilder需要371毫秒。String.format版本的实现比原来的实现慢,而StringBuilder版本的只是稍快一些。


尽管这三个方法在创建String的方式上不同,它们的共同点是调用execSQL,即仍然需要去做实际的语句的编译。因为所有的语句非常相似(它们只是cheese的name和origin不同),我们可以使用compileStatement(),在循环外仅仅去编译一次。这个实现如Listing 1-21所示。

Listing 1-21 编译SQLite语句

public void populateWithCompileStatement() {
    SQLiteStatement stmt = db.compileStatement("INSERT INTO cheese VALUES(?,?)");
    int i=0;
    for (String name : sCheeseNames) {
        String origin = sCheeseOrigins[i++];
        stmt.clearBindings();
        stmt.bindString(1, name);    // 用name替换第一个问号
        stmt.bindString(2, origin);    // 用origin替换第二个问号
        stmt.executeInsert();
    }
}

因为语句的编译仅需要一次而不是650次,而且binding value比起编译是更加轻量级的操作,这个方法的性能明显提高,它创建这个数据库仅需要268毫秒。它同样有着使代码更易读的优势。


Android同样提供了额外的API插入数值到数据库,通过ContentValues对象,它包含列名和数值。在Listing 1-22的实现中,实际上非常接近populateWithCompileStatement,“INSERT INTO cheese VALUES”字符串甚至没有出现,因为这部分插入语句暗示在da.insert()的调用中。然而,这个实现的性能低于我们使用populateWithCompileStatement()达到的,它需要352毫秒去完成。

Listing 1-22 使用ContentValues填充数据库

public void populateWithContentValues() {
    ContentValues values = new ContentValues();
    int i=0;
    for(String name : sCheeseNames) {
        String origin = sCheeseOrigins[i++];
        values.clear();
        values.put("name", name);
        values.put("origin", origin);
        db.insert("cheese", null, values);
    }
}

最快的实现通常也是最灵活的实现,因为在语句中允许更多的选择。比如,你可以通过"INSERT OR FAIL"或者"INSERT OR IGNORE"而不是简单的INSERT。

NOTE: Android 3.0中android.database和android.database.sqlite做了许多变化。比如,Activity类中的managerdQuery, startManagingCursor和stopManagingCursor方法被弃用,用CursorLoader代替。

Android同样定义了几个可以提高性能的类。比如,你可以使用DatabaseUtils.InsertHelper在数据库中插入多行,这样编译SQL的插入语句仅一次。现在它的实现和我们实现populateWithCompileStatement()的方式一致,尽管它并不提供同样的灵活性(比如, FAIL或者ROLLBACK)。

即使性能不是必须的,你也可以使用DatabaseUtils类中的静态方法去简化你的实现。

Transactions

上面的实例没有显式的创建任何事务,然而每次插入操作会自动创建一个,并且在插入完成后立即提交。显式的创建一个事务允许两件事情:
1) 原子提交(Atomic Commit)
2) 更好的性能

第一个Feature很重要但是不是从性能角度看的。原子提交(Atomic commit)意味着全部或者没有对数据库的修改发生。一个事务不可以仅提交一部分。在我们的例子中,我们可以认为所有的650个cheese插入是一个事务。我们成功的创建了cheese列表或者没有,但是我们对一部分成功没有兴趣。实现如Listing 1-23所示:

Listing 1-23 在一个事务中插入所有的Cheese

public void populateWithComileStatementOneTransaction () {
    try {
        db.beginTransaction();
        SQLiteStatement stmt = db.compileStatement("INSERT INTO cheese VALUES(?,?)");
        int i=0;
        for(String name : sCheeseNames) {
            String origin = sCheeseOrigins[i++];
            stmt.clearBindings();
            stmt.bindString(1, name);    // 使用name替换第一个问号
            stmt.bindString(2, origin);    // 使用origin替换第二个问号
            stmt.executeInsert();
        }
        db.setTransactionSuccessful();    // 移除这个调用,不会有任何改变提交
    } catch (Exception e) {
        // 在这里处理异常
    } finally {
        db.endTransaction();    // 这个调用必须在finally块中
    }
}

这个实现需要166毫秒执行完。这是一个非常大的提升(快了大约100毫秒),有人会说这两种实现都适用于大多数应用程序,因为通常不会这么快插入那么多行。实际上,大多数应用程序通常作为某个用户操作的响应,每次只访问一行。最重要的点是数据库是内存支持(memory-backed)的,并且没有存储到持久性存储器(SD卡或者内部Flash存储)。使用数据库,很多时间花费在访问持续存储器上(读/写),会比访问易失性存储器慢很多。通过在内部持续性存储器创建数据库,我们可以验证单个事务的效果。在持续性存储设备上创建数据库如Listing 1-24所示。

Listing 1-24 在存储器上创建数据库

public Cheeses (String path) {
    // path可能已经使用getDatabasePath("fromage.db")创建好了
    
    // 可能需要用一个mkdirs保证path存在
    // File file = new File(path);
    // File parent = new File(file.getParent());
    // parent.mkdirs();
    
    db = SQLiteDatabase.openOrCreateDatabase(path, null);
    db.execSQL("CREATE TABLE cheese (name TEXT, origin TEXT)"):
}

当数据库在存储器而不是内存的时候,populateWithCompileStatement()需要大约34秒完成(每行52毫秒),populateWithCompileStatementOneTransaction()需要少于200毫秒。不需要多说了,一个事务的方式对我们的问题来说是一个更好的解决方案。这些数据显然依赖于使用的存储器类型。在外部的SD卡上存储数据库会更慢因此使得一个事务的方式更加吸引人。

NOTE:当在存储器上创建数据库的时候保证父路径存在。参考Context.getDatabasePath和File.mkdirs。为了方便,使用SQLiteOpenHelper代替手动创建数据库。

查询

使查询更快的方式也限制了对数据库的访问,特别是在存储器上。一个数据库的查询简单的返回一个Cursor对象,可以用来迭代所有的结果。Listing 1-25给出了迭代所有行的两个方法。第一个方法创建了一个Cursor获取数据库的所有的两列,第二个方法仅获取第一列。

Listing 1-25 迭代所有的行

public void iterateBothColumns() {
    Cursor c = db.query("cheese", null, null, null, null, null, null);
    if (c.moveToFirst()) {
    	do {
    	} while (c.moveToNext());
    }
    c.close();    // 记得完成的时候关闭cursor(否则会在某点发生Exception)
}

public void iterateFirstColumn() {
    Cursor c = db.query("cheese", new String[] {"name"}, null, null, null, null, null);    // 唯一的不同
    if(c.moveToFirst()) {
        do {
        } while (c.moveToNext());
    }
    c.close();
}

就像期望的,因为根本不需要去从第二列读数据,第二个方法更快:23毫秒和61毫秒(当使用多事务)。当所有的行作为一个事务添加的时候,迭代所有的行更快:11毫秒(iterateBothColumns)和7毫秒(iterateFirsteColumn)。就像可以看到的,只获取你关心的数据。在查询的时候选择合适的参数调用可以导致不同的性能。你可以减少数据库的访问如果你仅需要特定数量的行,在查询调用的时候指定限制的参数。

TIP:更加深入的查找功能(使用indexing)考虑使用SQLite的FTS(full-text search)扩展(使用索引)。参考:www.sqlite.org/fts3.html

安卓ROM开发入门到精通 包含内容: 第一期主要为ROM开发,ROM定制技术资料,提供一些工具为主 ,让你学会简单做包,和基本的ROM DIY技巧,偶尔附加一些必要的教程。第二期针对ROM技术教程,细分知识点,重点剖析、解释,形成一系列的知识文档供查阅,目前大纲已列出,可以教你从零开始做包。 1.第一期---技术资料(维护更新): 更新日志: 1.书籍-Android系统级深入开发——移植与调试 2.开发工具-And... 阅读详情

相关推荐

Android/JAVA性能优化:从入门到精通(万字讲解!!!)

在当今快速发展的移动应用市场中,用户体验是决定应用成功与否的关键因素之一。无论是在Android还是其他平台上,应用的性能表现直接影响用户的满意度和应用的市场竞争力。作为开发者,掌握Java性能优化的技巧不仅能够提升应用的流畅度,还能延长应用的生命周期,从而在激烈的市场竞争中脱颖而出。本文将从内存管理、线程与并发、代码优化、网络优化、数据库优化等多个方面,深入探讨Java性能优化的策略和技巧,帮助开发者在实际开发中提升应用性能,优化用户体验。提示:以下是本篇文章正文内容,下面案例可供参考。

学无止境 1222

Android优化之优化Java代码

1、如果需要用很多对象时可以使用Cache,经常写Java的人可能会使用HashMap去实现Cache,但当Key是Integer的值时,Android为我们定义了一个更有效率的一个类:SparseArray类,它具有比HashMap更高的效率。 2、不同的API版本针对不同的功能已经做了优化,有些函数被弃用,启用新的调用函数,因此,在实现不同的API版本的时候,可针对不同的API进行不同程度的...

hyshucom 204

从零到精通:Android开发学习路径全解析

Android开发作为移动互联网核心技术之一,其技术栈经历了从基础SDK到现代架构的演进。理解Android系统架构需要扎实的Java/Kotlin基础,掌握Activity生命周期、UI组件等核心概念。在进阶阶段,开发者需要关注性能优化、架构设计等关键技术,如内存管理、MVVM模式实现等。通过项目实践和源码阅读,开发者可以深入理解Binder机制、AMS等底层原理。本文以知名博主stormzhang的学习路径为例,系统梳理了从Java基础到Flutter跨平台的完整学习框架,为移动开发者提供了一条清晰的技

weixin_34326558的博客 268

Android sqlite数据库操作

1.查询操作: 简单的直接使用SQLiteDatabase#query(table_name,columns,selections,selectionArgs,groupby,having,orderby,limits) 需要根据各种情况动态构建sql语句的,可以使用SQLiteQueryBuilder。用法如下: DatabaseHelper database = getDatabase...

淡淡的宁静的博客 3410

android游戏开发从入门到精通,androidstudio插件开发

如果基础知识有太多不会的就危险了,必须好好准备,这是躲不过的。这个阶段有不会的很正常,因为对方正在确定你的水平,但态度一定要积极主动,即使之前没有研究过,也要结合一些经验说出推测的结果,切忌直接说“我不会”。我只贴上我写过内容的链接,剩下的朋友们去网上一搜,或者去买本书看下就好了,建议看 《Java 编程思想》,不仅解答了 What 还有探讨 Why。我这次面试算法问的比较少,只手写过插入排序,建议把冒泡、插入、归并时间复杂度和实现熟悉熟悉,最好手写下,不然现场手写的时候容易出错。

2401_84408418的博客 1419

Android面试指南与参考答案——基于领星安卓开发职位要求

本文基于领星安卓开发职位要求,整理Android开发岗位常见面试问题与参考答案。核心内容包括:1.基础知识:Android四层架构、SDK组件及API使用;2.编程语言:Kotlin优势、Jetpack组件应用及MVVM/MVP架构对比;3.开发工具:性能优化方法及版本适配策略;4.实战经验:第三方SDK集成和APP发布流程。针对1-3年经验者及应届生,提供代码示例和项目实例说明,覆盖框架搭建、性能优化等关键技术点,帮助候选人系统准备面试,突出技术能力和问题解决思维。

郑伟强dev的专栏 1192

erased.java_java注解框架

我们经常会在java代码里面看到:“@Override”,“@Target”等等样子的东西,这些是什么?在java里面它们是“注解”。下面是百度百科的解释:java.lang.annotation.Retention可以在您定义Annotation型态时,指示编译器如何对待您的自定义 Annotation,预设上编译器会将Annotation资讯留在class档案中,但不被虚拟机器读取,而仅用于编...

weixin_32349699的博客 230

精通Android点九图片(.9.png)的制作与应用

使用点九图片的优势在于,它在减少资源文件大小的同时,能保证图形元素在不同设备上的适应性和一致性。较传统的图片处理方式而言,点九图片能有效减少开发人员对不同屏幕适配的工作量,从而提高应用性能和用户体验。点九图片是一种在Android开发中广泛使用的特殊格式图片,它允许图片在不同尺寸的屏幕上拉伸而不失真,同时保持边缘像素不变。这种图片格式对于创建可自适应屏幕尺寸和密度的应用图标、按钮、背景等界面元素特别有效。

weixin_42465332的博客 753

android sqlite3 并发,android SQLite 优化(三)使用事务 优化 insert

SQLite 没插入一条数据默认创建一次事务通过显示调用事务,可以提高SQLite操作的性能String[] sCheeseNames = {"a","b","a","b","a","b","a","b"};String[] sCheeseOrigins = {"aa","bb","aa","bb","aa","bb","aa","bb"};SQLiteDatabase db = SQLiteDa...

weixin_42573757的博客 204

sentinel滑动时间窗口算法学习

滑动时间窗口 先不说sentinel的算法实现,先说什么是滑动时间窗口, 我们在进行限流的时候,比如通过QPS进行限流,那假如我们以秒为单位,举个例子: 我设置了限流规则,qps是10 如果不使用滑动窗口算法,在统计qps的时候,就有可能会有问题,比如: 在0 - 500ms中的请求数是0,但是在500ms - 1000 ms的请求数是10;在1000ms - 1500ms 之间又进来了5个请求,此时只判断了1000ms - 2000 ms之间的请求数 因为没有把1S进行拆分多个窗口,所以在1000ms之后

小小少年的博客 3979

MT6816磁编码器在无人机电调中的实战应用:从选型到调试全记录

本文详细介绍了MT6816磁编码器在无人机电调系统中的实战应用,涵盖选型、硬件集成、软件配置到飞行测试的全流程。通过对比霍尔传感器和光电编码器,突出MT6816在角度分辨率、安装公差和抗振动能力等方面的优势,为无人机动力系统提供高精度控制解决方案。

pandas7gardener的博客 233

GreenDao3.0框架使用详解

最近将一个使用蓝牙设备测人体温度的穿戴设备项目做完了,有时间来总结下本项目中使用到的一些基础知识。上次写过关于GreenDao3.0框架在使用前的配置问题,可点击查看GreenDao3.0框架使用时IDE的配置问题,下面将详细的讲解下具体的使用过程。 编译后在gen包下会多出三个类,分别是TempDataDao,DaoMaster,DaoSession. TempData实体类里面是这

zhenghongwu的博客 4537

Altium Designer学习---如何进行SI仿真

Altium designer 如何进行SI仿真。         1、仿真电路中需要至少一块集成电路;             2、器件的IBIS模型;              3、在规则中必须设定电源网络和地网络;              4、建立SI规则约束;              5、层堆栈必须设置正确,电源平面必须连续;     建立的文件必须是一个工程,并把相应的文件放在工程目...

weixin_34050519的博客 4901

Android从入门到精通

全书共分15章,内容包括Android快速入门、Android模拟器与常用命令、用户界面设计、高级用户界面设计、基本程序单元Activity、Android应用核心Intent、Android事件处理、资源访问、图形图像处理技术、多媒体应用开发、Content Provider实现数据共享线程与消息处理、Service应用、网络编程及Internet应用和基于Android的家庭理财通。[Android.游戏开发入门](美)Mario.Zechner.插图版.pdf。

github_38514857的博客 878

ESP32-S3打造离线语音助手:从零部署自定义唤醒词与本地大模型推理【实战指南】

本文详细介绍了如何利用ESP32-S3芯片打造离线语音助手,包括自定义唤醒词训练与本地大模型推理的实战指南。通过硬件架构解析、音频处理优化及性能调优技巧,实现低延迟、高隐私保护的语音交互方案,特别适合智能家居和物联网应用。

weixin_30296405的博客 603

电阻基础知识及应用电路仿真(Multisim)

本文围绕硬件工程师必备的电阻知识,从基础知识、实操、应用仿真三方面做系统讲解:基础上明确电阻的核心参数、分类、串并联计算及核心特性;实操中详解贴片/色环电阻的阻值读取、贴片封装换算,重点区分0Ω电阻(贴装跳线,实现功能选通/调试等)与磁珠(高频吸噪)的差异及选型;应用上介绍限流、分压、上拉/下拉、阻抗匹配、过压/过流保护五大典型电路的设计公式、选型原则和实操要点,同时给出电阻通用的选型、测量和布线设计规范,形成完整的电阻应用知识体系。

XU157303764的博客 2773

想学Android开发,是否必须精通Java?

想学Android开发,必然需要先精通Java,其次c++,再后面是kotlin,基本代码上系统源码framework层面都是java和c++,基本上找不到任何kotlin,源码中只有几个简单app使用是kotlin。在这里,我为大家整理了一些列Android学习资料,有需要的朋友可以扫描下方二维码,获取更多相关资料。

Eqiqi的博客 1988

MinerU 本地部署完整指南:从零构建你的私有文档智能处理系统

摘要: MinerU是一款开源本地化文档解析工具,可将PDF、Word等文件智能转换为结构化Markdown,保留表格、公式、图片等元素。其核心优势包括: 隐私安全:完全离线处理,避免云端数据泄露风险; 高精度解析:基于深度学习还原文档逻辑结构,支持多格式输入; 易集成:提供RESTful API,适合金融、医疗等敏感场景。部署需Python 3.9+环境,支持CPU/GPU运行,推荐配置16GB内存及NVIDIA显卡。通过命令行或Docker即可快速启动,适用于知识库构建、RAG系统预处理等。

reset2021的博客 750

精通安卓性能优化-第一章(一)

第一章 优化Java代码 许多的安卓应用开发者从以往的经验对Java语言有很好的使用知识。从1995年出道以来,Java已经成为了一种非常流行的编程语言。有些调查指出Java在和其他语言比较的时候失去了光泽,比如Object-C或者C#,另外有些调查把Java列为最流行的语言。自然,随着移动设备的销量超过个人电脑和Android平台的成功(在2011年11月,每天激活700,000部),J...

路漫漫 其修远 1106

基于Python的新闻聚合与推荐系统:抓取多新闻网站内容并根据用户兴趣进行个性化推荐

本文介绍了如何使用Python构建一个新闻聚合与推荐系统,涵盖了从新闻数据抓取、用户兴趣建模到推荐算法实现的全过程。通过爬虫技术抓取新闻网站内容,使用TF-IDF、Word2Vec等算法进行内容分析,并通过推荐算法向用户推送个性化的新闻,最终帮助用户快速获取自己感兴趣的信息。你可以根据具体需求,进一步扩展和优化系统。例如,加入更多的推荐算法、优化爬虫的抓取效率、增强前端展示的互动性等。通过本文的指导,您应该能够构建一个完整的新闻聚合与推荐系统,并为用户提供个性化的新闻推荐服务。

2201_76125261的博客 1513

【漏洞复现】用友U9 UMWebService.asmx 任意文件读取漏洞

用友U9存在任意文件读取漏洞,未授权的攻击者可以通过该漏洞读取服务器任意文件,造成敏感信息泄露。

qq_67810151的博客 620

android性能优化从入门到精通

什么是性能优化 一款app除了要有强大的功能和交互外,在性能上也应该追求更高的要求,这样才能更好的提高用户体验 优化目的 性能指标 优化的方向 更快 流畅性 启动速度页面响应速度响应速度 更稳定 稳定性 避免出现应用崩溃(crash)避免出现应用无响应(ANR) 更省 资源节省性 内存大小安装包大小耗电量网络流量 优化详解 速度优化 内存优化 数据结构优化:数据结...

qq_23081779的博客 1765

霍尼韦尔SoftMaster使用说明

霍尼韦尔SoftMaster使用说明

Android性能优化:从入门到精通

本文从基础知识、优化方法和实战案例分析三个方面,详细介绍了Android性能优化的方法和技巧。性能优化是Android开发中不可或缺的一部分,对提升用户体验具有重要意义。开发者应掌握性能优化的基础知识,合理运用优化方法,以实现应用的高性能表现。未来,随着移动设备的性能不断提升,性能优化将更加重要。开发者需要关注新的优化技术和工具,不断更新优化策略,以满足用户对高性能应用的需求。同时,性能优化也需要与用户需求相结合,避免过度优化,确保应用的平衡发展。持续关注新技术。

2501_92486623的博客 357

深度学习工具包 DeepLearningToolbox

深度学习工具包Deprecation notice.-----This toolbox is outdated and no longer maintained.There are much better tools available for deep learning than this toolbox, e.g. [Theano](http://deeplearning.net/software/theano/), [torch](http://torch.ch/) or [tensorflow](http://www.tensorflow.org/)I would suggest you use one of the tools mentioned above rather than use this toolbox.Best, Rasmus.DeepLearnToolbox================A Matlab toolbox for Deep Learning.Deep Learning is a new subfield of machine learning that focuses on learning deep hierarchical models of data.It is inspired by the human brain's apparent deep (layered, hierarchical) architecture.A good overview of the theory of Deep Learning theory is[Learning Deep Architectures for AI](http://www.iro.umontreal.ca/~bengioy/papers/ftml_book.pdf)For a more informal introduction, see the following videos by Geoffrey Hinton and Andrew Ng.* [The Next Generation of Neural Networks](http://www.youtube.com/watch?v=AyzOUbkUf3M) (Hinton, 2007)* [Recent Developments in Deep Learning](http://www.youtube.com/watch?v=VdIURAu1-aU) (Hinton, 2010)* [Unsupervised Feature Learning and Deep Learning](http://www.youtube.com/watch?v=ZmNOAtZIgIk) (Ng, 2011)If you use this toolbox in your research please cite [Prediction as a candidate for learning deep hierarchical models of data](http://www2.imm.dtu.dk/pubdb/views/publication_details.php?id=6284)```@MASTERSTHESIS\{IMM2012-06284, author = "R. B. Palm", title = "Prediction as a candidate for learning deep hierarchical models of data", year = "2012",}```Contact: rasmusbergpalm at gmail dot comDirectories included in the toolbox-----------------------------------`NN/` - A library for Feedforward Backpropagation Neural Networks`CNN/` - A library for Convolutional Neural Networks`DBN/` - A library for Deep Belief Networks`SAE/` - A library for Stacked Auto-Encoders`CAE/` - A library for Convolutional Auto-Encoders`util/` - Utility functions used by the libraries`data/` - Data used by the examples`tests/` - unit tests to verify toolbox is workingFor references on each library check REFS.mdSetup-----1. Download.2. addpath(genpath('DeepLearnToolbox'));Example: Deep Belief Network---------------------```matlabfunction test_example_DBNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit RBM and visualize its weightsrand('state',0)dbn.sizes = [100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);figure; visualize(dbn.rbm{1}.W'); % Visualize the RBM weights%% ex2 train a 100-100 hidden unit DBN and use its weights to initialize a NNrand('state',0)%train dbndbn.sizes = [100 100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);%unfold dbn to nnnn = dbnunfoldtonn(dbn, 10);nn.activation_function = 'sigm';%train nnopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.10, 'Too big error');```Example: Stacked Auto-Encoders---------------------```matlabfunction test_example_SAEload mnist_uint8;train_x = double(train_x)/255;test_x = double(test_x)/255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit SDAE and use it to initialize a FFNN% Setup and train a stacked denoising autoencoder (SDAE)rand('state',0)sae = saesetup([784 100]);sae.ae{1}.activation_function = 'sigm';sae.ae{1}.learningRate = 1;sae.ae{1}.inputZeroMaskedFraction = 0.5;opts.numepochs = 1;opts.batchsize = 100;sae = saetrain(sae, train_x, opts);visualize(sae.ae{1}.W{1}(:,2:end)')% Use the SDAE to initialize a FFNNnn = nnsetup([784 100 10]);nn.activation_function = 'sigm';nn.learningRate = 1;nn.W{1} = sae.ae{1}.W{1};% Train the FFNNopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.16, 'Too big error');```Example: Convolutional Neural Nets---------------------```matlabfunction test_example_CNNload mnist_uint8;train_x = double(reshape(train_x',28,28,60000))/255;test_x = double(reshape(test_x',28,28,10000))/255;train_y = double(train_y');test_y = double(test_y');%% ex1 Train a 6c-2s-12c-2s Convolutional neural network %will run 1 epoch in about 200 second and get around 11% error. %With 100 epochs you'll get around 1.2% errorrand('state',0)cnn.layers = { struct('type', 'i') %input layer struct('type', 'c', 'outputmaps', 6, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %sub sampling layer struct('type', 'c', 'outputmaps', 12, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %subsampling layer};cnn = cnnsetup(cnn, train_x, train_y);opts.alpha = 1;opts.batchsize = 50;opts.numepochs = 1;cnn = cnntrain(cnn, train_x, train_y, opts);[er, bad] = cnntest(cnn, test_x, test_y);%plot mean squared errorfigure; plot(cnn.rL);assert(er<0.12, 'Too big error');```Example: Neural Networks---------------------```matlabfunction test_example_NNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);% normalize[train_x, mu, sigma] = zscore(train_x);test_x = normalize(test_x, mu, sigma);%% ex1 vanilla neural netrand('state',0)nn = nnsetup([784 100 10]);opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samples[nn, L] = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.08, 'Too big error');%% ex2 neural net with L2 weight decayrand('state',0)nn = nnsetup([784 100 10]);nn.weightPenaltyL2 = 1e-4; % L2 weight decayopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex3 neural net with dropoutrand('state',0)nn = nnsetup([784 100 10]);nn.dropoutFraction = 0.5; % Dropout fraction opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex4 neural net with sigmoid activation functionrand('state',0)nn = nnsetup([784 100 10]);nn.activation_function = 'sigm'; % Sigmoid activation functionnn.learningRate = 1; % Sigm require a lower learning rateopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex5 plotting functionalityrand('state',0)nn = nnsetup([784 20 10]);opts.numepochs = 5; % Number of full sweeps through datann.output = 'softmax'; % use softmax outputopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex6 neural net with sigmoid activation and plotting of validation and training error% split training data into training and validation datavx = train_x(1:10000,:);tx = train_x(10001:end,:);vy = train_y(1:10000,:);ty = train_y(10001:end,:);rand('state',0)nn = nnsetup([784 20 10]); nn.output = 'softmax'; % use softmax outputopts.numepochs = 5; % Number of full sweeps through dataopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, tx, ty, opts, vx, vy); % nntrain takes validation set as last two arguments (optionally)[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');```[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/rasmusbergpalm/deeplearntoolbox/trend.png)](https://bitdeli.com/free "Bitdeli Badge")

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

Android面试官:你究竟有多大的勇气,在简历上写了“精通”?

自定义 View 可以让我们产生更好的效果,app UI 美观,交互界面友好,用户青睐,用户留存率高,这就是app成功的第一步了。高级UI与自定义View有着不可分割的联系。自定义View其实并不难,为什么呢?因为自定义View无非就是显示+交互:显示由 onMeasure ->onLayout->onDraw的整个流程就将显示整个流程处理完了,而交互则是touch事件的处理;另外其他的一切你比如Canvas,Animation,Paint都是围绕着draw来进行的,所以我们需要搞懂其中的根本原理。

the shy 127

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

QtScrcpy安卓投屏完整攻略:从入门到精通

还在为手机屏幕太小而烦恼吗?想要在大屏幕上畅玩手游却不知从何下手?QtScrcpy这款开源安卓投屏工具正是你需要的解决方案!它能将手机屏幕实时投射到电脑,支持键盘鼠标操作,让你彻底告别触摸屏的局限。 ## 🎯 为什么选择QtScrcpy? **传统投屏痛点**: - 连接复杂,步骤繁琐 - 延迟高,画面卡顿 - 不支持键鼠操作 - 无法多设备管理 **QtScrcpy优势对比**: ✅ *

gitblog_00510的博客 3万+

3分钟精通安卓虚拟相机:从零配置到多场景实战

想要在安卓设备上实现摄像头内容的灵活替换吗?VCAM虚拟相机为您提供了完美的解决方案。这款基于Xposed框架的安卓虚拟相机支持安卓5.0及以上系统,能够为直播、视频会议、隐私保护等场景创建虚拟摄像头接口,让您的手机摄像体验更加丰富多彩! ## 🎯 基础入门:环境准备与快速启动 ### 必备条件清单 在开始使用VCAM虚拟相机前,请确保您的设备满足以下基本要求: - ✅ 已安装Xposed

gitblog_00738的博客 666
上一篇: 精通安卓性能优化-第一章(八)
下一篇: 精通安卓性能优化-第一章(十)- 总结
北冥_有鱼
博客等级 码龄19年 14粉丝 0原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值