安装数组的所有值的最快方法?

我有
char []

, 并且我想在相同的值下设置每个索引的值。
char

.

有一种明显的方法可以做到 /迭代/:


char f = '+';
char [] c = new char [50];
for/int i = 0; i < c.length; i++/{
c[i] = f;
}


但我想知道是否有一种我可以使用的方法
System.arraycopy

或者等同的东西,这将花费迭代的需要。 有没有办法做到这一点?

EDIT :

经过
Arrays.java



public static void fill/char[] a, int fromIndex, int toIndex, char val/ {
rangeCheck/a.length, fromIndex, toIndex/;
for /int i = fromIndex; i < toIndex; i++/
a[i] = val;
}


这完全是相同的过程,表明它可能不是最好的方法。

+1 建议的每个人
fill

反正 - 你完全正确,谢谢。
已邀请:

石油百科

赞同来自:

尝试
Arrays.fill/c, f/

:
http://docs.oracle.com/javase/ ... %255D,%20char%29

帅驴

赞同来自:

作为另一个选择和后代,我最近研究过这一点,并找到了一个解决方案,使您能够显着减少循环,通过部分工作类
http://docs.oracle.com/javase/ ... .html
, 哪一个 /如果一个 JVM, 您使用足够的智能/ 可以转换为运行
https://coderoad.ru/7367677/
:-


/*
* initialize a smaller piece of the array and use the System.arraycopy
* call to fill in the rest of the array in an expanding binary fashion
*/
public static void bytefill/byte[] array, byte value/ {
int len = array.length;

if /len > 0/{
array[0] = value;
}

//Value of i will be [1, 2, 4, 8, 16, 32, ..., len]
for /int i = 1; i < len; i += i/ {
System.arraycopy/array, 0, array, i, //len - i/ < i/ ? /len - i/ : i/;
}
}


这项决定是由 IBM 研究
https://ieeexplore.ieee.org/document/5387064
.

简化解释

从评论中如下,它设置了索引 0 您的值中的目标数组,然后使用
http://docs.oracle.com/javase/ ... .html
复制一个对象的类,即索引的对象 0 在索引中 1, 然后是这两个对象 /指数 0 和 1/ 在 2 和 3, 然后这四个物体 /0,1,2 和 3/ 在 4,5,6 和 7 等等...

效率 /当时

文章/

在快速里程,抓住
System.nanoTime//

之前和之后并计算出我发明的持续时间: -

这种方法 :

332,617 - 390,262

/'highest - lowest' 的 10 测试/


Float[] n = new Float[array.length]; //Fill with null

: 666,650

通过循环设置。 :

3,743,488

-

9,767,744

/'highest - lowest' 的 10 测试/


Arrays.fill

: 12,539,336


汇编 JVM 和 JIT

应该指出的是,随着发展 JVM 和 JIT 这种方法可能很过时,因为图书馆的优化和执行时间可以实现甚至超过这些数字,只需使用
fill//

.
在撰写文章时,它是我找到的最快选择。 已经提到了现在它可能不是这样的,但我没有检查过。 在这个美丽和诅咒 Java.

石油百科

赞同来自:

使用
Arrays.fill



char f = '+';
char [] c = new char [50];
Arrays.fill/c, f/

窦买办

赞同来自:

http://www.ensta-paristech.fr/ ... .html
优惠:


public static void bytefill/byte[] array, byte value/ {
int len = array.length;
if /len > 0/
array[0] = value;
for /int i = 1; i < len; i += i/
System.arraycopy/ array, 0, array, i,
//len - i/ < i/ ? /len - i/ : i/;
}


它基本上是这样做的 log2 /array.length/ 挑战 System.arraycopy, 我们希望哪种方式使用优化的实施 memcpy.

但是,是否仍然需要现代技术 Java JITs, 如 Oracle/Android JIT?

帅驴

赞同来自:

System.arraycopy - 这是我的答案。 如果有任何最佳方式,请告诉我。 TNH.


private static long[] r1 = new long[64];
private static long[][] r2 = new long[64][64];

/**Proved:
* {@link Arrays#fill/long[], long[]/} makes r2 has 64 references to r1 - not the answer;
* {@link Arrays#fill/long[], long/} sometimes slower than deep 2 looping.<br/>
*/
private static void testFillPerformance// {
SimpleDateFormat sdf = new SimpleDateFormat/"HH:mm:ss"/;
System.out.println/sdf.format/new Date////;
Arrays.fill/r1, 0l/;

long stamp0 = System.nanoTime//;
// Arrays.fill/r2, 0l/; -- exception
long stamp1 = System.nanoTime//;
// System.out.println/String.format/"Arrays.fill takes %s nano-seconds.", stamp1 - stamp0//;

stamp0 = System.nanoTime//;
for /int i = 0; i < 64; i++/ {
for /int j = 0; j < 64; j++/
r2[i][j] = 0l;
}
stamp1 = System.nanoTime//;
System.out.println/String.format/"Arrays' 2-looping takes %s nano-seconds.", stamp1 - stamp0//;

stamp0 = System.nanoTime//;
for /int i = 0; i < 64; i++/ {
System.arraycopy/r1, 0, r2[i], 0, 64/;
}
stamp1 = System.nanoTime//;
System.out.println/String.format/"System.arraycopy looping takes %s nano-seconds.", stamp1 - stamp0//;

stamp0 = System.nanoTime//;
Arrays.fill/r2, r1/;
stamp1 = System.nanoTime//;
System.out.println/String.format/"One round Arrays.fill takes %s nano-seconds.", stamp1 - stamp0//;

stamp0 = System.nanoTime//;
for /int i = 0; i < 64; i++/
Arrays.fill/r2[i], 0l/;
stamp1 = System.nanoTime//;
System.out.println/String.format/"Two rounds Arrays.fill takes %s nano-seconds.", stamp1 - stamp0//;
}


12:33:18

2循环阵列占据 133536 纳米秒。

System.arraycopy 循环占用 22070 纳米秒。

一轮 Arrays.fill 占据 9777 纳米秒。

两轮 Arrays.fill 占据 93028 纳米秒。





12:33:38

2循环阵列占据 133816 纳米秒。

System.arraycopy 循环占用 22070 纳米秒。

一轮 Arrays.fill 占据 17042 纳米秒。

两轮 Arrays.fill 占据 95263 纳米秒。





12:33:51

2循环阵列占据 199187 纳米秒。

System.arraycopy 循环占用 44140 纳米秒。

一轮 Arrays.fill 占据 19555 纳米秒。

两轮 Arrays.fill 占据 449219 纳米秒。





12:34:16

2循环阵列占据 199467 纳米秒。

System.arraycopy 循环占用 42464 纳米秒。

一轮 Arrays.fill 占据 17600 纳米秒。

两轮 Arrays.fill 占据 170971 纳米秒。





12:34:26

2循环阵列占据 198907 纳米秒。

System.arraycopy 循环占用 24584 纳米秒。

一轮 Arrays.fill 占据 10616 纳米秒。

两轮 Arrays.fill 占据 94426 纳米秒。

二哥

赞同来自:

如果你有另一个数组 char,
char[] b

, 而且你想更换
c


b

, 您可以使用
c=b.clone//;

.

喜特乐

赞同来自:

作为 Java-8 有四个
https://docs.oracle.com/javase ... .html
方法 setAll, 由提供以计算每个元素的生成函数设置指定数组的所有元素。

这四个过载



其中,他们采取了一系列原语,如下所示:

https://docs.oracle.com/javase ... tion-
IntToDoubleFunction/


https://docs.oracle.com/javase ... ator-
IntUnaryOperator/


https://docs.oracle.com/javase ... tion-
IntToLongFunction/

如何使用上述方法的示例:


// given an index, set the element at the specified index with the provided value
double [] doubles = new double[50];
Arrays.setAll/doubles, index -> 30D/;

// given an index, set the element at the specified index with the provided value
int [] ints = new int[50];
Arrays.setAll/ints, index -> 60/;

// given an index, set the element at the specified index with the provided value
long [] longs = new long[50];
Arrays.setAll/longs, index -> 90L/;


该方法提供的功能
setAll

, 获取元素索引并返回此索引的值。

您是否有兴趣涉及字符数组?

这是第四重新加载方法进入游戏
setAll

. 由于没有过载,消耗了一系列符号基元,因此我们拥有的唯一选择, - 这将更改我们符号数组的广告
Character[]

.

如果阵列类型的变化
Character

不合适,然后你可以返回方法 Arrays.fill.

使用方法的示例
setAll


Character[]

:


// given an index, set the element at the specified index with the provided value
Character[] character = new Character[50];
Arrays.setAll/characters, index -> '+'/;


虽然是

设置定义

值更容易使用该方法
Arrays.fill

, 不是方法
setAll

.

方法
setAll

您可以使用相同值的数组的所有元素,或生成偶数数组,奇数或任何其他公式的所有优点

例如。


int[] evenNumbers = new int[10]; 
Arrays.setAll/evenNumbers, i -> i * 2/;


还有几种方法过载。 parallelSetAll, 并行执行,尽管重要的是要注意该方法传输的功能 parallelSetAll,

必须摆脱副作用

.

输出

如果你的目标是

设置定义

数组的每个元素的值,然后使用过载
Arrays.fill

这将是最合适的选择。 但是,如果您希望按需更灵活或生成元素,最好使用
Arrays.setAll

或者
Arrays.parallelSetAll

/当它是合适的/.

小姐请别说爱

赞同来自:

厘米
http://docs.oracle.com/javase/ ... .html
方法 Arrays.fill:


char f = '+';
char [] c = new char [50];
Arrays.fill/c, f/;

郭文康

赞同来自:

Arrays.fill

可以满足您的需求

江南孤鹜

赞同来自:

Arrays.fill/myArray, 'c'/;


http://docs.oracle.com/javase/ ... %255D,%20char%29
虽然它可能在背景中产生一个循环,但因此没有比你所拥有的更有效 /除了保存日志线/. 如果您真正照顾效率,请尝试以下与上述内容相比:


int size = 50;
char[] array = new char[size];
for /int i=0; i<size; ;="" <="" array.size="" array[i]="c" code]="" div="" i++="" {="" }[="" 对于每次迭代。="" 请注意,以上并没有导致="">
<div class="answer_text">

[code]/**
* Assigns the specified char value to each element of the specified array
* of chars.
*
* @param a the array to be filled
* @param val the value to be stored in all elements of the array
*/
public static void fill/char[] a, char val/ {
for /int i = 0, len = a.length; i &lt; len; i++/
a[i] = val;
}


这是怎么做的 Arrays.fill.

/我想你可以调查 JNI 和使用
memset

./
</div>
<div class="answer_text">
回答罗斯画作略有改善。

为了

小的

Massif简单周期比方法更快 System.arraycopy, 由于与设置相关的开销成本 System.arraycopy. 因此,最好使用简单的循环填充阵列的前几个字节并转到 System.arraycopy 只有在完成的阵列具有一定尺寸时才。

初始循环的最佳大小将是 JVM 具体而且,当然,专门用于系统。


private static final int SMALL = 16;

public static void arrayFill/byte[] array, byte value/ {
int len = array.length;
int lenB = len &lt; SMALL ? len : SMALL;

for /int i = 0; i &lt; lenB; i++/ {
array[i] = value;
}

for /int i = SMALL; i &lt; len; i += i/ {
System.arraycopy/array, 0, array, i, len &lt; i + i ? len - i : i/;
}
}


</div>
<div class="answer_text">
您可以使用
arraycopy

, 但这取决于您是否可以提前定义原始数组, - 您是否需要每次填充不同的字符,或者您是否使用相同的符号填写阵列?

显然,填充长度很重要 - 或者您需要一个超过所有可能的目的地的来源,或者您需要多个循环 arraycopy 数据片段直到目的地已满。


char f = '+';
char[] c = new char[50];
for /int i = 0; i &lt; c.length; i++/
{
c[i] = f;
}

char[] d = new char[50];
System.arraycopy/c, 0, d, 0, d.length/;


</div>
<div class="answer_text">
arrays.fill是通用目的的最佳选择。
如果您需要填充大型数组,虽然是最后一个版本 idk 1.8 u102, 使用更快的方式 System.arraycopy.
您可以查看此替代实施。 Arrays.fill:

根据
https://github.com/zolyfarkas/ ... .java
JMH, 你几乎可以 2x 表现 boost 对于大型盾牌 /1000 +/

在任何情况下,都应仅在必要的地方使用这些实现。 JDKs Arrays.fill 必须是一个首选。
</div>
</size;>

涵秋

赞同来自:

/**
* Assigns the specified char value to each element of the specified array
* of chars.
*
* @param a the array to be filled
* @param val the value to be stored in all elements of the array
*/
public static void fill/char[] a, char val/ {
for /int i = 0, len = a.length; i < len; i++/
a[i] = val;
}


这是怎么做的 Arrays.fill.

/我想你可以调查 JNI 和使用
memset

./

奔跑吧少年

赞同来自:

回答罗斯画作略有改善。

为了

小的

Massif简单周期比方法更快 System.arraycopy, 由于与设置相关的开销成本 System.arraycopy. 因此,最好使用简单的循环填充阵列的前几个字节并转到 System.arraycopy 只有在完成的阵列具有一定尺寸时才。

初始循环的最佳大小将是 JVM 具体而且,当然,专门用于系统。


private static final int SMALL = 16;

public static void arrayFill/byte[] array, byte value/ {
int len = array.length;
int lenB = len < SMALL ? len : SMALL;

for /int i = 0; i < lenB; i++/ {
array[i] = value;
}

for /int i = SMALL; i < len; i += i/ {
System.arraycopy/array, 0, array, i, len < i + i ? len - i : i/;
}
}

窦买办

赞同来自:

您可以使用
arraycopy

, 但这取决于您是否可以提前定义原始数组, - 您是否需要每次填充不同的字符,或者您是否使用相同的符号填写阵列?

显然,填充长度很重要 - 或者您需要一个超过所有可能的目的地的来源,或者您需要多个循环 arraycopy 数据片段直到目的地已满。


char f = '+';
char[] c = new char[50];
for /int i = 0; i < c.length; i++/
{
c[i] = f;
}

char[] d = new char[50];
System.arraycopy/c, 0, d, 0, d.length/;

帅驴

赞同来自:

arrays.fill是通用目的的最佳选择。
如果您需要填充大型数组,虽然是最后一个版本 idk 1.8 u102, 使用更快的方式 System.arraycopy.
您可以查看此替代实施。 Arrays.fill:

根据
https://github.com/zolyfarkas/ ... .java
JMH, 你几乎可以 2x 表现 boost 对于大型盾牌 /1000 +/

在任何情况下,都应仅在必要的地方使用这些实现。 JDKs Arrays.fill 必须是一个首选。

要回复问题请先登录注册