设置数组的所有值的最快方法?

时间:2022-01-20 01:15:48

I have a char [], and I want to set the value of every index to the same char value.
There is the obvious way to do it (iteration):

我有一个char[],我希望将每个索引的值设置为相同的char值。有一种显而易见的方法(迭代):

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

But I was wondering if there's a way that I can utilize System.arraycopy or something equivalent that would bypass the need to iterate. Is there a way to do that?

但我想知道是否有一种方法可以让我利用系统。arraycopy或类似的东西可以绕过迭代的需要。有办法做到吗?

EDIT : From Arrays.java

编辑:从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;
    }

This is exactly the same process, which shows that there might not be a better way to do this.
+1 to everyone who suggested fill anyway - you're all correct and thank you.

这是完全相同的过程,这表明可能没有更好的方法来实现这一点。+1对每个建议填写的人-你都是正确的,谢谢。

14 个解决方案

#1


72  

Try Arrays.fill(c, f) : Arrays javadoc

尝试数组。fill(c, f):数组javadoc。

#2


33  

As another option and for posterity I was looking into this recently and found this article which offers a solution that allows a much shorter loop by handing some of the work off to the System class, which (if the JVM you're using is smart enough) can be turned into a memset operation:-

作为另一种选择,为后世研究最近,发现这篇文章提供了一个解决方案,允许更短的循环,将一些工作系统类,它(如果你使用的JVM是足够聪明可以变成memset操作:-

/*
 * 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;
  }

  for (int i = 1; i < len; i += i) {
    System.arraycopy(array, 0, array, i, ((len - i) < i) ? (len - i) : i);
  }
}

This solution was taken from the IBM research paper "Java server performance: A case study of building efficient, scalable Jvms" by R. Dimpsey, R. Arora, K. Kuiper.

这个解决方案取自IBM研究报告“Java服务器性能:一个构建高效、可伸缩的jvm的案例研究”,由R. Dimpsey, R. Arora, K. Kuiper。

Simplified explanation

简化的解释

As the comment suggests, this sets index 0 of the destination array to your value then uses the System class to copy one object i.e. the object at index 0 to index 1 then those two objects (index 0 and 1) into 2 and 3, then those four objects (0,1,2 and 3) into 4,5,6 and 7 and so on...

评论指出,这集索引0目标数组的值然后使用系统类复制一个对象即对象索引0到索引1然后这两个对象(索引0和1)到2和3,然后这四个对象(0、1、2和3)4、5、6和7等等……

Efficiency (at the point of writing)

效率(在写作的时候)

In a quick run through, grabbing the System.nanoTime() before and after and calculating a duration I came up with:-

在快速浏览中,获取系统。nanotime()之前和之后,并计算一个持续时间:-。

  • This method : 332,617 - 390,262 ('highest - lowest' from 10 tests)
  • 这个方法:332,617 - 390262(从10个测试中获得的最高分)
  • Float[] n = new Float[array.length]; //Fill with null : 666,650
  • 浮动的,浮动的;浮动的;浮动的;浮动的//填写空:666,650。
  • Setting via loop : 3,743,488 - 9,767,744 ('highest - lowest' from 10 tests)
  • 通过循环设置:3,743,488 - 9,767,744(从10个测试中“最高分”)
  • Arrays.fill : 12,539,336
  • 数组。填:12539336

The JVM and JIT compilation

JVM和JIT编译。

It should be noted that as the JVM and JIT evolves, this approach may well become obsolete as library and runtime optimisations could reach or even exceed these numbers simply using fill(). At the time of writing, this was the fastest option I had found. It has been mentioned this might not be the case now but I have not checked. This is the beauty and the curse of Java.

应该注意的是,随着JVM和JIT的发展,这种方法很可能会过时,因为库和运行时优化可以使用fill()来达到甚至超过这些数字。在写作的时候,这是我找到的最快的选择。有人说这可能不是现在的情况,但我没有检查。这就是Java的美丽和诅咒。

#3


9  

Use Arrays.fill

使用Arrays.fill

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

#4


6  

Java Programmer's FAQ Part B Sect 6 suggests:

Java程序员的FAQ部分B节建议:

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);
}

This essentially makes log2(array.length) calls to System.arraycopy which hopefully utilizes an optimized memcpy implementation.

这使得log2(array.length)调用系统。arraycopy希望利用一个优化的memcpy实现。

However, is this technique still required on modern Java JITs such as the Oracle/Android JIT?

然而,在现代Java JITs(如Oracle/Android JIT)中仍然需要这种技术吗?

#5


4  

System.arraycopy is my answer. Please let me know is there any better ways. Thx

系统。arraycopy是我的回答。请告诉我有没有更好的办法。谢谢

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
Arrays' 2-looping takes 133536 nano-seconds.
System.arraycopy looping takes 22070 nano-seconds.
One round Arrays.fill takes 9777 nano-seconds.
Two rounds Arrays.fill takes 93028 nano-seconds.

12:33:18阵列2循环需要133536纳米秒。系统。arraycopy循环需要22070奈秒。一轮数组。填充需要9777毫微秒。两轮数组。填充需要93028毫微秒。

12:33:38
Arrays' 2-looping takes 133816 nano-seconds.
System.arraycopy looping takes 22070 nano-seconds.
One round Arrays.fill takes 17042 nano-seconds.
Two rounds Arrays.fill takes 95263 nano-seconds.

数组的2循环需要133816纳米秒。系统。arraycopy循环需要22070奈秒。一轮数组。填充需要17042毫微秒。两轮数组。填充需要95263毫微秒。

12:33:51
Arrays' 2-looping takes 199187 nano-seconds.
System.arraycopy looping takes 44140 nano-seconds.
One round Arrays.fill takes 19555 nano-seconds.
Two rounds Arrays.fill takes 449219 nano-seconds.

12:33:51阵列' 2-循环需要199187纳米秒。系统。arraycopy循环需要44140纳米秒。一轮数组。填充需要19555毫微秒。两轮数组。填充需要449219毫微秒。

12:34:16
Arrays' 2-looping takes 199467 nano-seconds.
System.arraycopy looping takes 42464 nano-seconds.
One round Arrays.fill takes 17600 nano-seconds.
Two rounds Arrays.fill takes 170971 nano-seconds.

12:34:16数组的2循环需要199467纳米秒。系统。arraycopy循环需要42464纳米。一轮数组。填充需要17600毫微秒。两轮数组。填充需要170971毫微秒。

12:34:26
Arrays' 2-looping takes 198907 nano-seconds.
System.arraycopy looping takes 24584 nano-seconds.
One round Arrays.fill takes 10616 nano-seconds.
Two rounds Arrays.fill takes 94426 nano-seconds.

12:34:26阵列2-循环需要198907纳米秒。系统。arraycopy循环需要24584纳米。一轮数组。填充需要10616毫微秒。两轮数组。填充需要94426毫微秒。

#6


3  

If you have another array of char, char[] b and you want to replace c with b, you can use c=b.clone();.

如果你有另一组char, char[] b,你想用b替换c,你可以使用c=b.clone();

#7


2  

See Arrays.fill method:

看到数组。填写方法:

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

#8


1  

Arrays.fill might suit your needs

数组。fill可以满足你的需要。

#9


1  

Arrays.fill(myArray, 'c');

数组。填充(myArray ' c ');

Arrays.fill

Arrays.fill

Although it is quite possible that this is doing the loop in the background and is therefore not any more efficient than what you have (other than the lines of code savings). If you really care about efficiency, try the following in comparison to the above:

尽管这很有可能是在后台执行循环,因此并不比您拥有的(除了代码节省的行)更有效。如果你真的在乎效率,可以试试下面的方法:

int size = 50;
char[] array = new char[size];
for (int i=0; i<size; i++){
  array[i] = 'c';
}

Notice that the above doesn't call array.size() for each iteration.

注意,上面的每个迭代都不调用array.size()。

#10


1  

   /**
     * 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;
    }

That's the way Arrays.fill does it.

这样的数组。填补它。

(I suppose you could drop into JNI and use memset.)

(我想你可以加入JNI,使用memset。)

#11


0  

You could use arraycopy but it depends on whether you can predefine the source array, - do you need a different character fill each time, or are you filling arrays repeatedly with the same char?

您可以使用arraycopy,但这取决于您是否可以预先定义源数组——您是否需要每次都填充不同的字符,还是重复使用相同的字符填充数组?

Clearly the length of the fill matters - either you need a source that is bigger than all possible destinations, or you need a loop to repeatedly arraycopy a chunk of data until the destination is full.

显然,填充的长度很重要——要么需要一个比所有可能的目的地都大的源,要么需要一个循环来反复地复制一大块数据,直到目的地是满的。

    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);

#12


0  

Arrays.fill is the best option for general purpose use. If you need to fill large arrays though as of latest idk 1.8 u102, there is a faster way that leverages System.arraycopy. You can take a look at this alternate Arrays.fill implementation:

数组。填充是一般用途的最佳选择。如果您需要填充大型数组,尽管最新的idk 1.8 u102,有一种更快的方式利用System.arraycopy。您可以看看这个备用数组。填补实现:

According to the JMH benchmarks you can get almost 2x performance boost for large arrays (1000 +)

根据JMH基准测试,您可以获得近2倍的大数组性能提升(1000 +)

In any case, these implementations should be used only where needed. JDKs Arrays.fill should be the preferred choice.

无论如何,这些实现应该只在需要的地方使用。jdk数组。填充应该是首选。

#13


0  

As of Java-8, there are four variants of the setAll method which sets all elements of the specified array, using a provided generator function to compute each element.

在Java-8中,有四种不同的setAll方法,它设置指定数组的所有元素,使用提供的生成器函数来计算每个元素。

Of those four overloads only three of them accept an array of primitives declared as such:

在这4个重载中,只有3个接受了这样的原语数组:





Examples of how to use the aforementioned methods:

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

// 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);

The function provided to the setAll method receives the element index and returns a value for that index.

提供给setAll方法的函数接收元素索引并返回该索引的值。

you may be wondering how about characters array?

你可能想知道字符数组?

This is where the fourth overload of the setAll method comes into play. As there is no overload that consumes an array of character primitives, the only option we have is to change the declaration of our character array to a type Character[].

这就是第四个超载的setAll方法开始发挥作用。由于没有消耗大量字符原语的重载,所以我们唯一的选择是将字符数组的声明更改为类型字符[]。

If changing the type of the array to Character is not appropriate then you can fall back to the Arrays.fill method.

如果将数组的类型更改为字符是不合适的,那么您可以返回到数组。填充方法。

Example of using the setAll method with Character[]:

使用setAll方法与字符[]:

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

Although, it's simpler to use the Arrays.fill method rather than the setAll method to set a specific value.

尽管,使用数组更简单。填充方法而不是setAll方法来设置特定的值。

The setAll method has the advantage that you can either set all the elements of the array to have the same value or generate an array of even numbers, odd numbers or any other formula:

setAll方法的优点是,可以将数组的所有元素设置为具有相同的值或生成偶数、奇数或任何其他公式的数组:

e.g.

如。

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

There's also several overloads of the parallelSetAll method which is executed in parallel, although it's important to note that the function passed to the parallelSetAll method must be side-effect free.

并行执行的并行方法也有几个重载,尽管需要注意的是,传递给并行高度表的函数必须是无副作用的。

Conclusion

结论

If your goal is simply to set a specific value for each element of the array then using the Arrays.fill overloads would be the most appropriate option. However, if you want to be more flexible or generate elements on demand then using the Arrays.setAll or Arrays.parallelSetAll (when appropriate) would be the option to go for.

如果您的目标只是为数组的每个元素设置一个特定的值,然后使用数组。填充过载将是最合适的选择。但是,如果您想要更灵活,或者在需要时使用数组来生成元素。setAll或数组。在适当的时候(适当的时候)是可以选择的。

#14


0  

I have a minor improvement on Ross Drew's answer.

我对罗斯·德鲁的回答有一点改进。

For a small array, a simple loop is faster than the System.arraycopy approach, because of the overhead associated with setting up System.arraycopy. Therefore, it's better to fill the first few bytes of the array using a simple loop, and only move to System.arraycopy when the filled array has a certain size.

对于一个小数组,一个简单的循环比系统快。arraycopy方法,因为与建立System.arraycopy相关的开销。因此,最好使用一个简单的循环来填充数组的前几个字节,并且只移动到系统。当填充数组有一定的大小时,arraycopy。

The optimal size of the initial loop will be JVM specific and system specific of course.

初始循环的最优大小将是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);
  }
}

#1


72  

Try Arrays.fill(c, f) : Arrays javadoc

尝试数组。fill(c, f):数组javadoc。

#2


33  

As another option and for posterity I was looking into this recently and found this article which offers a solution that allows a much shorter loop by handing some of the work off to the System class, which (if the JVM you're using is smart enough) can be turned into a memset operation:-

作为另一种选择,为后世研究最近,发现这篇文章提供了一个解决方案,允许更短的循环,将一些工作系统类,它(如果你使用的JVM是足够聪明可以变成memset操作:-

/*
 * 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;
  }

  for (int i = 1; i < len; i += i) {
    System.arraycopy(array, 0, array, i, ((len - i) < i) ? (len - i) : i);
  }
}

This solution was taken from the IBM research paper "Java server performance: A case study of building efficient, scalable Jvms" by R. Dimpsey, R. Arora, K. Kuiper.

这个解决方案取自IBM研究报告“Java服务器性能:一个构建高效、可伸缩的jvm的案例研究”,由R. Dimpsey, R. Arora, K. Kuiper。

Simplified explanation

简化的解释

As the comment suggests, this sets index 0 of the destination array to your value then uses the System class to copy one object i.e. the object at index 0 to index 1 then those two objects (index 0 and 1) into 2 and 3, then those four objects (0,1,2 and 3) into 4,5,6 and 7 and so on...

评论指出,这集索引0目标数组的值然后使用系统类复制一个对象即对象索引0到索引1然后这两个对象(索引0和1)到2和3,然后这四个对象(0、1、2和3)4、5、6和7等等……

Efficiency (at the point of writing)

效率(在写作的时候)

In a quick run through, grabbing the System.nanoTime() before and after and calculating a duration I came up with:-

在快速浏览中,获取系统。nanotime()之前和之后,并计算一个持续时间:-。

  • This method : 332,617 - 390,262 ('highest - lowest' from 10 tests)
  • 这个方法:332,617 - 390262(从10个测试中获得的最高分)
  • Float[] n = new Float[array.length]; //Fill with null : 666,650
  • 浮动的,浮动的;浮动的;浮动的;浮动的//填写空:666,650。
  • Setting via loop : 3,743,488 - 9,767,744 ('highest - lowest' from 10 tests)
  • 通过循环设置:3,743,488 - 9,767,744(从10个测试中“最高分”)
  • Arrays.fill : 12,539,336
  • 数组。填:12539336

The JVM and JIT compilation

JVM和JIT编译。

It should be noted that as the JVM and JIT evolves, this approach may well become obsolete as library and runtime optimisations could reach or even exceed these numbers simply using fill(). At the time of writing, this was the fastest option I had found. It has been mentioned this might not be the case now but I have not checked. This is the beauty and the curse of Java.

应该注意的是,随着JVM和JIT的发展,这种方法很可能会过时,因为库和运行时优化可以使用fill()来达到甚至超过这些数字。在写作的时候,这是我找到的最快的选择。有人说这可能不是现在的情况,但我没有检查。这就是Java的美丽和诅咒。

#3


9  

Use Arrays.fill

使用Arrays.fill

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

#4


6  

Java Programmer's FAQ Part B Sect 6 suggests:

Java程序员的FAQ部分B节建议:

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);
}

This essentially makes log2(array.length) calls to System.arraycopy which hopefully utilizes an optimized memcpy implementation.

这使得log2(array.length)调用系统。arraycopy希望利用一个优化的memcpy实现。

However, is this technique still required on modern Java JITs such as the Oracle/Android JIT?

然而,在现代Java JITs(如Oracle/Android JIT)中仍然需要这种技术吗?

#5


4  

System.arraycopy is my answer. Please let me know is there any better ways. Thx

系统。arraycopy是我的回答。请告诉我有没有更好的办法。谢谢

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
Arrays' 2-looping takes 133536 nano-seconds.
System.arraycopy looping takes 22070 nano-seconds.
One round Arrays.fill takes 9777 nano-seconds.
Two rounds Arrays.fill takes 93028 nano-seconds.

12:33:18阵列2循环需要133536纳米秒。系统。arraycopy循环需要22070奈秒。一轮数组。填充需要9777毫微秒。两轮数组。填充需要93028毫微秒。

12:33:38
Arrays' 2-looping takes 133816 nano-seconds.
System.arraycopy looping takes 22070 nano-seconds.
One round Arrays.fill takes 17042 nano-seconds.
Two rounds Arrays.fill takes 95263 nano-seconds.

数组的2循环需要133816纳米秒。系统。arraycopy循环需要22070奈秒。一轮数组。填充需要17042毫微秒。两轮数组。填充需要95263毫微秒。

12:33:51
Arrays' 2-looping takes 199187 nano-seconds.
System.arraycopy looping takes 44140 nano-seconds.
One round Arrays.fill takes 19555 nano-seconds.
Two rounds Arrays.fill takes 449219 nano-seconds.

12:33:51阵列' 2-循环需要199187纳米秒。系统。arraycopy循环需要44140纳米秒。一轮数组。填充需要19555毫微秒。两轮数组。填充需要449219毫微秒。

12:34:16
Arrays' 2-looping takes 199467 nano-seconds.
System.arraycopy looping takes 42464 nano-seconds.
One round Arrays.fill takes 17600 nano-seconds.
Two rounds Arrays.fill takes 170971 nano-seconds.

12:34:16数组的2循环需要199467纳米秒。系统。arraycopy循环需要42464纳米。一轮数组。填充需要17600毫微秒。两轮数组。填充需要170971毫微秒。

12:34:26
Arrays' 2-looping takes 198907 nano-seconds.
System.arraycopy looping takes 24584 nano-seconds.
One round Arrays.fill takes 10616 nano-seconds.
Two rounds Arrays.fill takes 94426 nano-seconds.

12:34:26阵列2-循环需要198907纳米秒。系统。arraycopy循环需要24584纳米。一轮数组。填充需要10616毫微秒。两轮数组。填充需要94426毫微秒。

#6


3  

If you have another array of char, char[] b and you want to replace c with b, you can use c=b.clone();.

如果你有另一组char, char[] b,你想用b替换c,你可以使用c=b.clone();

#7


2  

See Arrays.fill method:

看到数组。填写方法:

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

#8


1  

Arrays.fill might suit your needs

数组。fill可以满足你的需要。

#9


1  

Arrays.fill(myArray, 'c');

数组。填充(myArray ' c ');

Arrays.fill

Arrays.fill

Although it is quite possible that this is doing the loop in the background and is therefore not any more efficient than what you have (other than the lines of code savings). If you really care about efficiency, try the following in comparison to the above:

尽管这很有可能是在后台执行循环,因此并不比您拥有的(除了代码节省的行)更有效。如果你真的在乎效率,可以试试下面的方法:

int size = 50;
char[] array = new char[size];
for (int i=0; i<size; i++){
  array[i] = 'c';
}

Notice that the above doesn't call array.size() for each iteration.

注意,上面的每个迭代都不调用array.size()。

#10


1  

   /**
     * 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;
    }

That's the way Arrays.fill does it.

这样的数组。填补它。

(I suppose you could drop into JNI and use memset.)

(我想你可以加入JNI,使用memset。)

#11


0  

You could use arraycopy but it depends on whether you can predefine the source array, - do you need a different character fill each time, or are you filling arrays repeatedly with the same char?

您可以使用arraycopy,但这取决于您是否可以预先定义源数组——您是否需要每次都填充不同的字符,还是重复使用相同的字符填充数组?

Clearly the length of the fill matters - either you need a source that is bigger than all possible destinations, or you need a loop to repeatedly arraycopy a chunk of data until the destination is full.

显然,填充的长度很重要——要么需要一个比所有可能的目的地都大的源,要么需要一个循环来反复地复制一大块数据,直到目的地是满的。

    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);

#12


0  

Arrays.fill is the best option for general purpose use. If you need to fill large arrays though as of latest idk 1.8 u102, there is a faster way that leverages System.arraycopy. You can take a look at this alternate Arrays.fill implementation:

数组。填充是一般用途的最佳选择。如果您需要填充大型数组,尽管最新的idk 1.8 u102,有一种更快的方式利用System.arraycopy。您可以看看这个备用数组。填补实现:

According to the JMH benchmarks you can get almost 2x performance boost for large arrays (1000 +)

根据JMH基准测试,您可以获得近2倍的大数组性能提升(1000 +)

In any case, these implementations should be used only where needed. JDKs Arrays.fill should be the preferred choice.

无论如何,这些实现应该只在需要的地方使用。jdk数组。填充应该是首选。

#13


0  

As of Java-8, there are four variants of the setAll method which sets all elements of the specified array, using a provided generator function to compute each element.

在Java-8中,有四种不同的setAll方法,它设置指定数组的所有元素,使用提供的生成器函数来计算每个元素。

Of those four overloads only three of them accept an array of primitives declared as such:

在这4个重载中,只有3个接受了这样的原语数组:





Examples of how to use the aforementioned methods:

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

// 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);

The function provided to the setAll method receives the element index and returns a value for that index.

提供给setAll方法的函数接收元素索引并返回该索引的值。

you may be wondering how about characters array?

你可能想知道字符数组?

This is where the fourth overload of the setAll method comes into play. As there is no overload that consumes an array of character primitives, the only option we have is to change the declaration of our character array to a type Character[].

这就是第四个超载的setAll方法开始发挥作用。由于没有消耗大量字符原语的重载,所以我们唯一的选择是将字符数组的声明更改为类型字符[]。

If changing the type of the array to Character is not appropriate then you can fall back to the Arrays.fill method.

如果将数组的类型更改为字符是不合适的,那么您可以返回到数组。填充方法。

Example of using the setAll method with Character[]:

使用setAll方法与字符[]:

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

Although, it's simpler to use the Arrays.fill method rather than the setAll method to set a specific value.

尽管,使用数组更简单。填充方法而不是setAll方法来设置特定的值。

The setAll method has the advantage that you can either set all the elements of the array to have the same value or generate an array of even numbers, odd numbers or any other formula:

setAll方法的优点是,可以将数组的所有元素设置为具有相同的值或生成偶数、奇数或任何其他公式的数组:

e.g.

如。

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

There's also several overloads of the parallelSetAll method which is executed in parallel, although it's important to note that the function passed to the parallelSetAll method must be side-effect free.

并行执行的并行方法也有几个重载,尽管需要注意的是,传递给并行高度表的函数必须是无副作用的。

Conclusion

结论

If your goal is simply to set a specific value for each element of the array then using the Arrays.fill overloads would be the most appropriate option. However, if you want to be more flexible or generate elements on demand then using the Arrays.setAll or Arrays.parallelSetAll (when appropriate) would be the option to go for.

如果您的目标只是为数组的每个元素设置一个特定的值,然后使用数组。填充过载将是最合适的选择。但是,如果您想要更灵活,或者在需要时使用数组来生成元素。setAll或数组。在适当的时候(适当的时候)是可以选择的。

#14


0  

I have a minor improvement on Ross Drew's answer.

我对罗斯·德鲁的回答有一点改进。

For a small array, a simple loop is faster than the System.arraycopy approach, because of the overhead associated with setting up System.arraycopy. Therefore, it's better to fill the first few bytes of the array using a simple loop, and only move to System.arraycopy when the filled array has a certain size.

对于一个小数组,一个简单的循环比系统快。arraycopy方法,因为与建立System.arraycopy相关的开销。因此,最好使用一个简单的循环来填充数组的前几个字节,并且只移动到系统。当填充数组有一定的大小时,arraycopy。

The optimal size of the initial loop will be JVM specific and system specific of course.

初始循环的最优大小将是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);
  }
}