2013-04-17 7 views
7

저는 (간단한!) 선형 대수학 라이브러리를 작성하고 있습니다.왜이 방법이 핫 스폿입니까?

public double next() { 
    double result; 

    if(hasNext()) 
     result = vis[i++].next(); 
    else 
     throw new IllegalStateException("No next value"); 

    return result; 
} 
: matrix multiplication의 구현에서, VisualVM 성능 샘플 큰 행렬 (5K X 120K)를 승산 할 때, 알고리즘은 다음과 같은 방법으로 (즉, "자체 시간")의 시간의 85 %를 소비하는 것을 말해되고

너무 자세히 설명하지 않고 (죄송합니다. 더 많은 코드를 공유 할 수 없습니다.)이 메서드는 next() 행렬에 대한 "반복기"메서드입니다. (여러분은이 메소드가 vis에 저장되어있는 개별 열 반복자로 구성된 행 반복자로 생각할 수있는 클래스를 생각할 수 있습니다.) 반복자이므로이 메소드가 많이 호출되는 것은 놀랍지 않지만 입니다.이 프로그램은 많은 시간을 에 보내는데이 방법은입니다. 이 방법은 너무 많은 것을하지 않으므로 여기에 시간을 보내는 이유는 무엇입니까?

  1. 내가 치는거야 "잡았다"VisualVM과 일부 있습니까 : 여기

    특정 질문에 내가 부탁 해요입니까? 예를 들어, JIT가 VisualVM을 어떤 방식 으로든 혼란스럽게 만들면 VisualVM이 시간을 잘못된 방법으로 지정하게됩니다.
  2. 왜 프로그램이 여기에 시간을 보내고 있습니까? 이 방법은 너무 많이하지 않습니다. 특히, vis 배열은 곱셈되는 행렬의 데이터보다 훨씬 작기 때문에 캐시 효과가이 문제를 설명한다고 생각하지 않습니다. 경우

는 여기 유용 내가 위에서 붙여 넣기 방법의 jad 분해입니다 :

public double next() 
{ 
    double result; 
    if(hasNext()) 
//* 0 0:aload_0   
//* 1 1:invokevirtual #88 <Method boolean hasNext()> 
//* 2 4:ifeq   32 
     result = vis[i++].next(); 
// 3 7:aload_0   
// 4 8:getfield  #42 <Field VectorIterator[] vis> 
// 5 11:aload_0   
// 6 12:dup    
// 7 13:getfield  #28 <Field int i> 
// 8 16:dup_x1   
// 9 17:iconst_1   
// 10 18:iadd    
// 11 19:putfield  #28 <Field int i> 
// 12 22:aaload   
// 13 23:invokeinterface #72 <Method double VectorIterator.next()> 
// 14 28:dstore_1   
    else 
//* 15 29:goto   42 
     throw new IllegalStateException("No next value"); 
// 16 32:new    #89 <Class IllegalStateException> 
// 17 35:dup    
// 18 36:ldc1   #91 <String "No next value"> 
// 19 38:invokespecial #93 <Method void IllegalStateException(String)> 
// 20 41:athrow   
    return result; 
// 21 42:dload_1   
// 22 43:dreturn   
} 

감사합니다 사전에 당신의 도움들에 대해!

+1

나는 hasNext()와 next() 호출에 의존한다고 생각한다. 왜냐하면 우리는 기본 객체를 모르기 때문에 O (1)이고 메소드는 꽤 빠르다 고 가정한다. 우리가 알고있는 모든 것에 대해 태양을 1000 배나 돌아간다. – RuntimeError

+0

@RuntimeError, "self time"*은 메소드 자체에 소비 된 시간만을 포함해야한다. 그러므로 hasNext()와 sub -next() 내가 아는 한이 방법에 기인 한 자아 시간과 관련이 없습니다. (다르게 알고 계시면 교정 해주십시오.) – sigpwned

+1

'next'가 스스로를 호출합니까 (재귀 적입니까?)? 그것은 재귀가 깊다면 시간이 걸리는 이유가 될 것입니다. – assylias

답변

8

VisualVM이 프로파일 링에서 JRE의 메소드를 무시하도록 지시 되었기 때문에이 방법은 핫스팟처럼 보였습니다. 그 "무시 된"방법에 소비 된 시간은 (외면적으로) 호출 스택의 무시되지 않는 최상위 항목의 자체 시간으로 변환되었습니다.

다음은 데이터를 잘못 만들고있는 "프로필 패키지 안 함"설정을 포함하여 VisualVM의 설정 화면입니다. '클래스 무시'설정을 조정하려면 (1) 빨간색으로 강조 표시된 '설정'확인란을 클릭 한 다음 (2) 파란색으로 강조 표시된 클래스 설정을 조정해야합니다.

VisualVM Settings Screen

당신이 무슨 일을하는지에 따라, 아마 의미가 적어도 java.*javax.* 패키지를 무시하지 않을 수 있습니다.

1

VisualVM을 경험하지 못했습니다.

우선 통계를 수집하기 위해 바이트 코드를 계측하는지 확인하십시오. 그렇다면 더 이상 보지 마십시오. 짧은 방법을 도구로 사용하면 항상 자체 시간이 초과됩니다 (시간 측정 및 통계 카운터 증가는 메서드 자체보다 시간이 오래 걸림).

그러나 iterator가 계산 자체보다 더 많은 시간을 소비하는 것은 항상 가능합니다. 행렬을 요약하는 것을 상상해보십시오. 로컬 합 변수에 float 값을 추가하는 것은 메서드 호출, 불변성 검사 및 마지막으로 배열 액세스보다 훨씬 적은 시간을 소비합니다.

+0

방금 ​​VisualVM의 설명서를 확인했습니다. 계측 프로파일 러입니다. – Durandal

+0

그러나 나는 이것을 "샘플링"모드에서 사용하고 있다고 믿는다. 즉, 주기적으로 (아마도 수십 또는 초당 수백 번) CPU를 "정지"시켜야하고 그 다음에 각 스레드에서 어떤 일이 일어나는지보아야한다. 그 때의 프로세스. 이것은 경험에서 나온 눈에 잘 띄지 않는 접근법이며, IMO에서 보낸 시간을 임의로 팽창 시켜서는 안됩니다. – sigpwned

+0

글쎄 VisualVM에 익숙하지 않지만 설명서에 "응용 프로그램 성능을 분석 할 때 VisualVM * 도구는 프로파일 링 된 응용 프로그램의 모든 메소드 *"라고 CPU 프로파일 링 아래에 나와 있습니다 (http://visualvm.java.net/profiler.html).). 당신이하고있는 일이나 다른 선택 사항을 사용하고 있는지 확실하지 않은가요? – Durandal

1

프로필러를 잊어 버립니다. 몇 번 멈추고 스택을 조사하십시오. 85 %의 시간이 루틴에 들어가면 각 일시 중지에 대해 85 %의 확률로 루틴의 위치와 정확히 어디서 왔는지 정확하게 알 수 있습니다. 매트릭스를 곱하는 과정에서 어디에 있는지 알 수 있습니다. 수천 개의 샘플에서 그 사실을 알리지 않습니다.

내 자신의 감각은이 i++보다 훨씬 느린 될 것입니다 모든 단일 요소를 한 후, 다음 hasNext을하고, 그 함수를 호출 Next을하고 있다는 것입니다.