我们知道,Java总是在创建时初始化数组.即new int [1000000]总是返回一个所有元素= 0的数组.我明白这是Object数组必须的,但是对于原始数组(除了可能是Boolean),在大多数情况下我们不关心初始值.

有没有人知道避免这种初始化的方法?

解决方法

我做了一些调查.在Java中创建未初始化的数组没有合法的方法.即使JNI NewXxxArray也创建了初始化的数组.因此,不可能准确地知道阵列归零的成本.不过我做了一些测量:

1)具有不同数组大小的1000字节数组创建

long t0 = System.currentTimeMillis();
        for(int i = 0; i < 1000; i++) {
//          byte[] a1 = new byte[1];
            byte[] a1 = new byte[1000000];
        }
        System.out.println(System.currentTimeMillis() - t0);

在我的PC上,字节[1]为1ms,字节[1000000]为〜500 ms.听起来令我印象深刻

2)我们在JDK中没有一个快速(本机)方法来填充数组,Arrays.fill太慢了,所以让我们看看至少有1,000,000个大小的数组的1000次拷贝与本机的System.arraycopy

byte[] a1 = new byte[1000000];
    byte[] a2 = new byte[1000000];
    for(int i = 0; i < 1000; i++) {
        System.arraycopy(a1,a2,1000000);
    }

是700毫秒

它给我理由相信a)创建长阵列是昂贵的b)它似乎是昂贵的,因为无用的初始化.

3)让我们来sun.misc.Unsafe http://www.javasourcecode.org/html/open-source/jdk/jdk-6u23/sun/misc/Unsafe.html.它受到外部使用的保护,但不要太多

Field f = Unsafe.class.getDeclaredField("theUnsafe");
    f.setAccessible(true);
    Unsafe unsafe = (Unsafe)f.get(null);

这是内存分配测试的成本

for(int i = 0; i < 1000; i++) {
        long m = u.allocateMemory(1000000);
    }

它需要< 1 ms,如果你还记得,对于新的字节[1000000],需要500ms. 4)Unsafe没有直接的方法来处理数组.它需要知道类字段,但反射在数组中不显示字段.关于数组内部结构没有太多的信息,我想这是JVM /平台的具体.然而,像其他任何Java对象一样,头域也是如此.在我的PC / JVM上看起来像

header - 8 bytes
int length - 4 bytes
long bufferAddress - 8 bytes

现在,使用Unsafe,我将创建byte [10],分配一个10字节的内存缓冲区,并将其用作我的数组元素:

byte[] a = new byte[10];
    System.out.println(Arrays.toString(a));
    long mem = unsafe.allocateMemory(10);
    unsafe.putLong(a,12,mem);
    System.out.println(Arrays.toString(a));

它打印

[0,0]
[8,15,-114,24,0]

您可以看到thay数组的数据未初始化.

现在我将更改我们的数组长度(尽管它仍然指向10字节内存)

unsafe.putInt(a,8,1000000);
    System.out.println(a.length);

它显示1000000.这只是为了证明这个想法是有效的.

现在性能测试.我将创建一个空字节数组a1,分配一个1000000字节的缓冲区,将这个缓冲区分配给a1一组a1.length = 10000000

long t0 = System.currentTimeMillis();
    for(int i = 0; i < 1000; i++) {
        byte[] a1 = new byte[0];
        long mem1 = unsafe.allocateMemory(1000000);
        unsafe.putLong(a1,mem);
        unsafe.putInt(a1,1000000);
    }
    System.out.println(System.currentTimeMillis() - t0);

需要10ms.

5)在C中有malloc和alloc,malloc只是分配内存块,calloc也用零初始化它.

CPP

...
JNIEXPORT void JNICALL Java_Test_malloc(jnienv *env,jobject obj,jint n) {
     malloc(n);
}

java的

private native static void malloc(int n);

for (int i = 0; i < 500; i++) {
    malloc(1000000);
}

结果malloc – 78 ms; calloc – 468 ms

结论

>似乎Java数组创建速度很慢,因为无用的元素归零.
>我们不能改变它,但Oracle可以.不需要更改JLS中的任何内容,只需将本地方法添加到java.lang.reflect.Array中即可

public static native xxx [] newUninitialziedXxxArray(int size);

适用于所有原始数字类型(byte-double)和char类型.它可以在JDK中使用,就像在java.util.Arrays中一样

public static int[] copyOf(int[] original,int newLength) {
        int[] copy = Array.newUninitializedIntArray(newLength);
        System.arraycopy(original,copy,Math.min(original.length,newLength));
        ...

或java.lang.String

public String concat(String str) {
        ...   
        char[] buf = Array.newUninitializedChararray(count + otherLen);
        getChars(0,count,buf,0);
        ...

java – 有没有办法创建一个基本的数组没有初始化?的更多相关文章

  1. html5使用canvas实现弹幕功能示例

    这篇文章主要介绍了html5使用canvas实现弹幕功能示例的相关资料,需要的朋友可以参考下

  2. three.js模拟实现太阳系行星体系功能

    这篇文章主要介绍了three.js模拟实现太阳系行星体系功能,本文通过实例代码给大家介绍的非常详细,具有一定的参考借鉴价值,需要的朋友可以参考下

  3. 前端实现弹幕效果的方法总结(包含css3和canvas的实现方式)

    这篇文章主要介绍了前端实现弹幕效果的方法总结(包含css3和canvas的实现方式)的相关资料,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧

  4. H5 canvas实现贪吃蛇小游戏

    本篇文章主要介绍了H5 canvas实现贪吃蛇小游戏,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧

  5. HTML5页面无缝闪开的问题及解决方案

    这篇文章主要介绍了HTML5页面无缝闪开方案,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下

  6. ios – parse.com用于键,预期字符串的无效类型,但是得到了数组

    我尝试将我的数据保存到parse.com.我已经预先在parse.com上创建了一个名为’SomeClass’的类.它有一个名为’mySpecialColumn’的列,其数据类型为String.这是我尝试使用以下代码保存数据的代码:如果我运行这个我得到:错误:密钥mySpecialColumn的无效类型,预期字符串,但得到数组这就是我在parse.com上的核心外观:有谁知道我为什么会收到这个错误?

  7. ios – 上下文类型’NSFastEnumeration’不能与数组文字一起使用

    斯威夫特3,你会这样做吗?解决方法正如您所发现的,您不能使用as-casting将数组文字的类型指定为NSFastEnumeration.您需要找到一个符合NSFastEnumeration的正确类,在您的情况下它是NSArray.通常写这样的东西:

  8. ios – 为什么,将nil作为参数从Objc C发送到swift类初始化器,用新对象替换nil参数

    除非属性本身被声明为nonnull:

  9. ios – 获取资产目录文件夹中所有图像的数组

    在iOS中,是否可以获取资产目录文件夹中的图像数组?我不确定为什么会对此进行投票.我真的不知道从哪里开始.我的另一种方法是创建文件夹中所有文件的plist,但它似乎是多余的.我无法添加任何代码,因为我会添加什么?

  10. ios – 在Swift中对MKCircle进行子类化

    我想通过添加另一个String属性来继承MKCircle,我们称之为“代码”.这个属性不是可选的和常量的,所以我必须从初始化器设置它,对吧?有没有办法定义一个单一的便利初始化器,在这种情况下需要3个参数?本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请发送邮件至dio@foxmail.com举报,一经查实,本站将立刻删除。

随机推荐

  1. 基于EJB技术的商务预订系统的开发

    用EJB结构开发的应用程序是可伸缩的、事务型的、多用户安全的。总的来说,EJB是一个组件事务监控的标准服务器端的组件模型。基于EJB技术的系统结构模型EJB结构是一个服务端组件结构,是一个层次性结构,其结构模型如图1所示。图2:商务预订系统的构架EntityBean是为了现实世界的对象建造的模型,这些对象通常是数据库的一些持久记录。

  2. Java利用POI实现导入导出Excel表格

    这篇文章主要为大家详细介绍了Java利用POI实现导入导出Excel表格,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

  3. Mybatis分页插件PageHelper手写实现示例

    这篇文章主要为大家介绍了Mybatis分页插件PageHelper手写实现示例,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

  4. (jsp/html)网页上嵌入播放器(常用播放器代码整理)

    网页上嵌入播放器,只要在HTML上添加以上代码就OK了,下面整理了一些常用的播放器代码,总有一款适合你,感兴趣的朋友可以参考下哈,希望对你有所帮助

  5. Java 阻塞队列BlockingQueue详解

    本文详细介绍了BlockingQueue家庭中的所有成员,包括他们各自的功能以及常见使用场景,通过实例代码介绍了Java 阻塞队列BlockingQueue的相关知识,需要的朋友可以参考下

  6. Java异常Exception详细讲解

    异常就是不正常,比如当我们身体出现了异常我们会根据身体情况选择喝开水、吃药、看病、等 异常处理方法。 java异常处理机制是我们java语言使用异常处理机制为程序提供了错误处理的能力,程序出现的错误,程序可以安全的退出,以保证程序正常的运行等

  7. Java Bean 作用域及它的几种类型介绍

    这篇文章主要介绍了Java Bean作用域及它的几种类型介绍,Spring框架作为一个管理Bean的IoC容器,那么Bean自然是Spring中的重要资源了,那Bean的作用域又是什么,接下来我们一起进入文章详细学习吧

  8. 面试突击之跨域问题的解决方案详解

    跨域问题本质是浏览器的一种保护机制,它的初衷是为了保证用户的安全,防止恶意网站窃取数据。那怎么解决这个问题呢?接下来我们一起来看

  9. Mybatis-Plus接口BaseMapper与Services使用详解

    这篇文章主要为大家介绍了Mybatis-Plus接口BaseMapper与Services使用详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

  10. mybatis-plus雪花算法增强idworker的实现

    今天聊聊在mybatis-plus中引入分布式ID生成框架idworker,进一步增强实现生成分布式唯一ID,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

返回
顶部