Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/jsp/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 应用程序启动时在Android中快速加载(反序列化)2MB数据_Java_Android_Performance_Deserialization_Protocol Buffers - Fatal编程技术网

Java 应用程序启动时在Android中快速加载(反序列化)2MB数据

Java 应用程序启动时在Android中快速加载(反序列化)2MB数据,java,android,performance,deserialization,protocol-buffers,Java,Android,Performance,Deserialization,Protocol Buffers,我需要在Android应用程序启动时快速加载大约2MB的数据。 我真的需要所有这些数据在内存中,所以像SQLite之类的东西不是替代品 数据由大约3000个int[][]数组组成。数组维度平均约为[7][7] 我首先在我的桌面上实现了一些原型,并将其移植到android上。在桌面上,我只使用了Java的(反)序列化。在我的台式计算机上反序列化这些数据大约需要90毫秒 然而,在安卓2.2.1上,在我的HTC Magic上,同样的过程大约需要15秒(!)。这是如此缓慢,如果我不去反序列化在一个单独的

我需要在Android应用程序启动时快速加载大约2MB的数据。 我真的需要所有这些数据在内存中,所以像SQLite之类的东西不是替代品

数据由大约3000个
int[][]
数组组成。数组维度平均约为[7][7]

我首先在我的桌面上实现了一些原型,并将其移植到android上。在桌面上,我只使用了Java的(反)序列化。在我的台式计算机上反序列化这些数据大约需要90毫秒

然而,在安卓2.2.1上,在我的HTC Magic上,同样的过程大约需要15秒(!)。这是如此缓慢,如果我不去反序列化在一个单独的thred,我的应用程序将被杀死。总而言之,这是令人无法接受的缓慢

我做错了什么?我应该吗

  • 切换到协议缓冲区之类的东西?这真的会加速几个数量级的反序列化过程吗?毕竟,我反序列化的不是复杂的对象,只是
    int[][]]
    array
  • 设计我自己的自定义二进制文件格式?我以前从未这样做过,也不知道从哪里开始
  • 做点别的吗

几个月前,我在一个项目中遇到了类似的问题。我认为你应该把你的文件分成不同的部分,并且只加载用户选择的相关部分。
希望这会有帮助

几个月前,我在一个项目中遇到了同样的问题。我认为你应该把你的文件分成不同的部分,并且只加载用户选择的相关部分。
希望这会有帮助

为什么不绕过内置反序列化,使用直接二进制I/O? 当速度是您最关心的问题,而不一定是编程的易用性时,您无法战胜它

对于输出,伪代码如下所示:

write number of arrays
for each array
  write n,m array sizes
  for each element of array
    write array element
对于输入,伪代码为:

read number of arrays
for each array
  read n,m array sizes
  allocate the array
  for each element of array
    read array element
当你读/写二进制数字时,你绕过了二进制和字符之间的所有转换。
速度应仅受文件存储介质的数据传输速率限制。

为什么不绕过内置的反序列化,使用直接二进制I/O? 当速度是您最关心的问题,而不一定是编程的易用性时,您无法战胜它

对于输出,伪代码如下所示:

write number of arrays
for each array
  write n,m array sizes
  for each element of array
    write array element
对于输入,伪代码为:

read number of arrays
for each array
  read n,m array sizes
  allocate the array
  for each element of array
    read array element
当你读/写二进制数字时,你绕过了二进制和字符之间的所有转换。
速度应仅受文件存储介质的数据传输速率的限制。

我不知道您的数据,但如果您优化循环,将对反序列化时间产生难以置信的影响

若你们看下面的例子


我不知道你的数据,但如果你优化你的循环,它将影响反序列化时间难以置信

若你们看下面的例子


正如迈克·邓拉维(Mike Dunlavey)所建议的那样,在尝试了几件事情之后,直接二进制I/O似乎速度最快。我几乎一字不差地使用了他的草稿。但是为了完整,如果其他人想尝试,我会在这里发布我的完整代码;尽管这是非常基本的,没有任何精神检查。这是为了读取这样的二进制流;写作是完全相似的

import java.io.*;

public static int[][][] readBinaryInt(String filename) throws IOException {
    DataInputStream in = new DataInputStream(
            new BufferedInputStream(new FileInputStream(filename)));
int dimOfData = in.readInt();
int[][][] patternijk = new int[dimofData][][];
for(int i=0;i<dimofData;i++) {
    int dimStrokes = in.readInt(); 
    int[][] patternjk = new int[dimStrokes][];      
    for(int j=0;j<dimStrokes;j++) {
        int dimPoints = in.readInt();
        int[] patternk = new int[dimPoints];
        for(int k=0;k<dimPoints;k++) {
                patternk[k] = in.readInt();
            }
            patternjk[j] = patternk;
    }
    patternijk[i] = patternjk;
    }
    in.close();
return patternijk;  
}
import java.io.*;
公共静态int[][]readBinaryInt(字符串文件名)引发IOException{
DataInputStream in=新的DataInputStream(
新的BufferedInputStream(新的FileInputStream(文件名));
int-dimOfData=in.readInt();
int[][]patternijk=新的int[dimofData][];

对于(int i=0;i在尝试了几件事情之后,正如Mike Dunlavey所建议的那样,直接二进制i/O似乎速度最快。我几乎一字不差地使用了他的略图版本。但是,为了完整性,如果其他人想尝试,我将在这里发布我的完整代码;尽管它非常基本,没有任何形式的健全检查。这是用于阅读这样的二进制str写作是绝对相似的

import java.io.*;

public static int[][][] readBinaryInt(String filename) throws IOException {
    DataInputStream in = new DataInputStream(
            new BufferedInputStream(new FileInputStream(filename)));
int dimOfData = in.readInt();
int[][][] patternijk = new int[dimofData][][];
for(int i=0;i<dimofData;i++) {
    int dimStrokes = in.readInt(); 
    int[][] patternjk = new int[dimStrokes][];      
    for(int j=0;j<dimStrokes;j++) {
        int dimPoints = in.readInt();
        int[] patternk = new int[dimPoints];
        for(int k=0;k<dimPoints;k++) {
                patternk[k] = in.readInt();
            }
            patternjk[j] = patternk;
    }
    patternijk[i] = patternjk;
    }
    in.close();
return patternijk;  
}
import java.io.*;
公共静态int[][]readBinaryInt(字符串文件名)引发IOException{
DataInputStream in=新的DataInputStream(
新的BufferedInputStream(新的FileInputStream(文件名));
int-dimOfData=in.readInt();
int[][]patternijk=新的int[dimofData][];

对于(int i=0;谢谢你的回答。但如上所述,我真的需要对所有数据进行操作,从而将所有数据都存储在内存中。只加载部分数据不是一个选项。你确实需要同时对所有数据进行操作吗?谢谢你的回答。但如上所述,我真的需要对所有数据进行操作,从而将所有数据都存储在内存中y、 仅加载部分不是一个选项。而且您确实需要同时对所有数据进行操作?数据是什么?什么是“需要..在内存中”真正的意思是什么?当您花时间运行Traceview并准确确定在何处以及为什么花费“15秒(!)”,您发现了什么?次要说明:协议缓冲区不直接支持锯齿数组。但是它支持向量,并且有一个“压缩”选项使其有效,但是您需要存储一个
重复的某物
,其中
某物
有一个
重复的int data=1[packed=true];
。数据是什么?什么“需要..内存中的”真的是指?当您花时间运行Traceview并准确确定“15秒(!)”花费的位置和原因时,您发现了什么?次要说明:协议缓冲区不直接支持交错数组。但它支持向量,并且有一个“打包”的选项使其有效,但您需要存储一个
重复的某物
,其中
某物
具有一个
重复的int data=1[packed=true];
。Nit:序列化/反序列化并不意味着“二进制和字符之间的转换”;甚至像这样的解决方案也必须以某种方式将二进制流数据移动到
int[][]
(或提供类似IntBuffer的包装器),因为与C不同的是,没有办法“强制转换该指针值”。@pst:Thx。根据我的经验,因为这基本上是一个I/