나는 자바를 처음 접했고 어젯밤에 코드를 실행하고 있었고, 이것은 실제로 나를 귀찮게했다. 나는 for 루프에서 모든 X 출력을 표시하는 간단한 프로그램을 작성하고 있었고 모듈러스를 variable % variablevs variable % 5000또는 기타 로 사용했을 때 성능이 크게 떨어졌습니다 . 누군가 이것이 왜 이것이 원인인지 설명 할 수 있습니까? 그래서 나는 더 나아질 수 있습니다 ...
여기에 "효율적인"코드가 있습니다 (구문이 틀리면 죄송합니다. 컴퓨터에 코드가 없습니다.)
long startNum = 0;
long stopNum = 1000000000L;
for (long i = startNum; i <= stopNum; i++){
if (i % 50000 == 0) {
System.out.println(i);
}
}
다음은 "비효율적 인 코드"입니다
long startNum = 0;
long stopNum = 1000000000L;
long progressCheck = 50000;
for (long i = startNum; i <= stopNum; i++){
if (i % progressCheck == 0) {
System.out.println(i);
}
}
차이를 측정하는 날짜 변수가 있었고 일단 충분히 길어지면 첫 번째는 50ms가 걸리고 다른 하나는 12 초 정도 걸렸습니다. PC가 내 것보다 효율적이거나 그렇지 않은 경우 를 늘리 stopNum거나 줄여야 할 수도 있습니다 progressCheck.
웹 에서이 질문을 찾았지만 답을 찾을 수 없습니다. 아마 대답하지 않을 수도 있습니다.
편집 : 내 질문이 그렇게 인기가 있다고 기대하지 않았습니다. 모든 답변을 주셔서 감사합니다. 나는 매 반마다 벤치 마크를 수행했으며 비효율적 인 코드는 1/4 초 대 10 초가 걸리거나 걸리는 시간이 상당히 길었습니다. 그들이 println을 사용하고 있지만 둘 다 같은 양을하고 있기 때문에, 특히 불일치가 반복 가능하기 때문에 그것이 많이 기울어 질 것이라고는 생각하지 않습니다. 답변은 Java를 처음 사용하기 때문에 투표가 지금 어떤 답변이 가장 적합한지를 결정하게 할 것입니다. 수요일까지 하나 골라 볼게요.
EDIT2 : 오늘 밤 또 다른 테스트를 할 것입니다. 여기서 모듈러스 대신 변수를 증가시키고 progressCheck에 도달하면 하나를 수행 한 다음 해당 변수를 0으로 재설정합니다.
편집 3.5 :
이 코드를 사용했고 아래에 결과를 보여 드리겠습니다. 훌륭한 도움을 주셔서 감사합니다! 또한 long의 짧은 값을 0과 비교하려고 시도했기 때문에 새로운 모든 검사는 "65536"번 반복되어 반복적으로 동일하게 발생합니다.
public class Main {
public static void main(String[] args) {
long startNum = 0;
long stopNum = 1000000000L;
long progressCheck = 65536;
final long finalProgressCheck = 50000;
long date;
// using a fixed value
date = System.currentTimeMillis();
for (long i = startNum; i <= stopNum; i++) {
if (i % 65536 == 0) {
System.out.println(i);
}
}
long final1 = System.currentTimeMillis() - date;
date = System.currentTimeMillis();
//using a variable
for (long i = startNum; i <= stopNum; i++) {
if (i % progressCheck == 0) {
System.out.println(i);
}
}
long final2 = System.currentTimeMillis() - date;
date = System.currentTimeMillis();
// using a final declared variable
for (long i = startNum; i <= stopNum; i++) {
if (i % finalProgressCheck == 0) {
System.out.println(i);
}
}
long final3 = System.currentTimeMillis() - date;
date = System.currentTimeMillis();
// using increments to determine progressCheck
int increment = 0;
for (long i = startNum; i <= stopNum; i++) {
if (increment == 65536) {
System.out.println(i);
increment = 0;
}
increment++;
}
//using a short conversion
long final4 = System.currentTimeMillis() - date;
date = System.currentTimeMillis();
for (long i = startNum; i <= stopNum; i++) {
if ((short)i == 0) {
System.out.println(i);
}
}
long final5 = System.currentTimeMillis() - date;
System.out.println(
"\nfixed = " + final1 + " ms " + "\nvariable = " + final2 + " ms " + "\nfinal variable = " + final3 + " ms " + "\nincrement = " + final4 + " ms" + "\nShort Conversion = " + final5 + " ms");
}
}
결과 :
- 고정 = 874ms (일반적으로 약 1000ms이지만 2의 거듭 제곱으로 인해 더 빠름)
- 변수 = 8590ms
- 최종 변수 = 1944ms (50000 사용시 ~ 1000ms)
- 증분 = 1904ms
- 짧은 변환 = 679ms
분할이 부족하여 단기 전환이 "빠른"방식보다 23 % 빠릅니다. 이것은 흥미 롭습니다. 256 회마다 (또는 거기에 대해) 무언가를 보여 주거나 비교해야 할 경우,이를 수행하고
if ((byte)integer == 0) {'Perform progress check code here'}
FINAL INTERNALING NOTE, 65536 (정수는 아님)과 함께 "최종 선언 된 변수"에서 모듈러스를 사용하는 것은 고정 된 값보다 (느린) 속도의 절반입니다. 이전에는 거의 같은 속도로 벤치마킹했습니다.
final앞에 추가하면progressCheck둘 다 같은 속도로 다시 실행됩니다. 따라서 컴파일러 또는 JIT는 루프progressCheck가 일정 하다는 것을 알고 루프를 최적화 할 수 있다고 생각 합니다.