2014-10-11 5 views
3

잠시 동안 C를 작성하지 않았기 때문에 혼란 스럽습니다. C++에서는 전체 구조체를 복사하지 않기 위해 참조로 전달합니다. 이것은 C에도 적용됩니까? 복사를 피하기 위해 그들을 수정하고 싶지 않더라도 포인터로 전달해야합니까? 두 구조체가 동일한 경우를 확인하는 기능을 위해, 우리는 더 나은함수에서 구조체를 전달하는 방법은 무엇입니까?

int equal(MyRecord* a, MyRecord* b);

을 수행하고 (때문에 포인터의) 비트를 가독성을 저하 말하면

,

또는

int equal(MyRecord a, MyRecord b);

의 성능은 동일합니까?

+1

C 관련 질문 인 것처럼 보였으므로 C++ 태그를 제거했습니다. – Shoe

+0

첫 번째 경우에는 struct의 주소를 전달하거나 MyRecord에 포인터 유형을 typedef하고 두 번째 예제를 사용할 수 있지만 참조로 전달하려면 다음과 같이 주소를 전달해야합니다. 인수 – Andrea

+3

그리고 필요하다면''const'''를 사용하여 기밀 변경을 막을 수 있습니다. –

답변

3

구조체의 크기에 따라 더 빠르다는 것은 입니다. 이는 호출 된 함수 내에서 사용됩니다.

구조체가 포인터보다 크지 않은 경우 값으로 전달하는 것이 가장 좋습니다 (복사 할 데이터의 양 또는 더 작음).

구조체가 포인터보다 큰 경우 호출 된 함수 내에서 발생하는 액세스 유형에 크게 의존합니다 (ABI 사양에서도 나타남). 많은 랜덤 액세스가 구조체에 만들어지면, 함수 내에서 포인터 간접 참조가 발생하기 때문에 포인터보다 크더라도 값으로 전달하는 것이 더 빠를 수 있습니다.

구조체가 포인터보다 큰 경우 무엇이 더 빠르는지 알아 내기 위해 프로필을 작성해야합니다.

0

자신에게 말하는 이유 때문에 포인터를 전달하는 것이 더 빠릅니다.

실제로이 경우 C++보다 읽기 쉽습니다. 호출에서 포인터를 전달하면 매개 변수가 호출 된 함수에 의해 변경 될 수 있음을 인정합니다. C++ 참조를 사용하면 호출 만보고 호출 된 함수 원형을 체크 아웃해야 참조를 사용하는지 확인할 수 있습니다.

+0

요점은 C VS C++ 가독성이 아니라 처음 쓴 문장입니다. 나는 조금 기다렸다가 아마도 당신의 대답을 받아 들일 것입니다. :) – gsamaras

+0

당신은 내 +1을 잡을 것이지만, 그 지점에 더 집중하기 위해 또 다른 대답을 받아 들일 것입니다. :) – gsamaras

+1

글쎄, 당신은 더 많은 의문이 있다면 그냥 물어보십시오. 초기 질문에서 충분히 알 것 같았습니다. – SukkoPera

6

은 종종 포인터를 전달하는 것은 빠르다 - 그리고 r1r2 지역 struct 변수입니다 당신은 equal(&r1, &r2) 전화 할게. 형식을 const 포인터로 const 구조로 선언 할 수 있습니다 (이 경우 optimizing compiler이 더 효율적인 코드를 생성하는 데 도움이됩니다). restrict 키워드를 사용할 수도 있습니다 (equal과 동일한 포인터 (예 : equal(&r1,&r1), 즉 pointer aliasing없이)라고 절대로 호출하지 않을 것이라고 확신하는 경우

그러나, 어떤 특정 ABIscalling conventions 몇 몇 특정 구조에 대해서는 특별히 처리를 강제 할 수있다. 예를 들어, x86-64 ABI for Linux (및 Unix SVR4)는 두 개의 포인터 또는 정수 값을 갖는 struct두 개의 레지스터를 통해 반환된다고 말합니다. 일반적으로 레지스터에서 포인터로 메모리 영역을 수정하는 것보다 빠릅니다. YMMV.

더 빨리 무엇인지 알아 보려면 실제로 벤치 마크해야합니다. 그러나 값이 큰 struct (예 : 최소 4 개의 정수 필드 또는 포인터 필드 포함)을 전달하는 것은 포인터를 전달하는 것보다 거의 항상 느립니다.

현재, 현재 데스크탑 및 랩톱 프로세서에서 중요한 점은 CPU cache입니다. 자주 사용되는 데이터를 L1 또는 L2 캐시에 보관하면 성능이 향상됩니다. this을 참조하십시오.

+0

컴파일러가 최적화를 할 수 있는지 여부는 함수 프로토 타입의 문제가 아니지만 개체 자체의 주소는 전달됩니다. (그러나 객체가'const' 인 경우,이 함수는 추악한 캐스트를 피하기 위해 일치하는 프로토 타입을 필요로합니다. 그 주석은 실제로 잘못이 아니지만, 어떻게 든 IMO 포인트를 놓칩니다.) – mafso

+0

잘 모르겠습니다. 컴파일러가'const' 구조체에 대한 포인터를 사용하고 컴파일러가'equal (& r1, & r1)'을 호출하면 최적화가 더 좋을 것 같네요. –

+0

'clang'을 가지고 놀았습니다 ('gcc'를 그렇게 할 수 없었습니다). 최적화), 그리고 나와 함께있어 ... 문제는 : const 구조체가 아닌 경우 해당 주소를 가져 와서 const 포인터를 기다리는 함수에 전달하면이 함수는 const를 캐스팅하고 목적. 반대의 경우에도 마찬가지입니다 : const 객체가 있고, 주소를 가져 와서 const를 캐스팅하고, 함수에 건네 주면, 함수는 가리키는 객체를 수정하면 안됩니다. 프로토 타입은 중요하지 않습니다. 유일한 것은 객체 자체의 선언 된 타입입니다. – mafso

관련 문제