programing

저수준 코드에 Objective-C를 사용하면 내 iPhone 앱이 성능 저하를 일으키나요?

nasanasas 2020. 11. 7. 10:11
반응형

저수준 코드에 Objective-C를 사용하면 내 iPhone 앱이 성능 저하를 일으키나요?


iPhone 또는 기타 휴대용 하드웨어에서 CPU 집약적 또는 GPU 집약적 애플리케이션을 프로그래밍 할 때 코드를 빠르게 만들기 위해 현명한 알고리즘 결정을 내려야합니다.

그러나 사용중인 언어가 다른 언어보다 성능이 좋지 않으면 훌륭한 알고리즘 선택도 느려질 수 있습니다.

Objective-C를 C ++, 특히 iPhone에서 비교하는 하드 데이터가 있습니까?하지만 Mac 데스크톱에서만 다양한 유사한 언어 측면의 성능을 볼 수 있습니까? 나는 C와 Objective-C를 비교 하는 이 기사에 매우 익숙 하지만 이것은 두 객체 지향 언어를 서로 비교하는 더 큰 질문입니다.

예를 들어, C ++ vtable 조회가 Obj-C 메시지보다 정말 빠릅니까? 얼마나 빨리요? 스레딩, 다형성, 정렬 등. 중복 된 객체 모델과 다양한 테스트 코드를 사용하여 프로젝트를 빌드하기 전에 누군가 이미이 작업을 수행했는지 여부와 결과가 어디인지 알고 싶습니다. 이러한 유형의 테스트 및 비교는 그 자체로 프로젝트이며 상당한 시간이 걸릴 수 있습니다. 아마도 이것은 하나의 프로젝트는 아니지만 두 개의 출력 만 비교할 수 있습니다.

저는 전도가 아닌 하드 데이터를 찾고 있습니다. 많은 분들처럼 저도 여러 가지 이유로 두 언어를 사랑하고 싫어합니다. 또한 누군가가 이와 똑같은 것을 적극적으로 추구한다면 최종 결과를보기 위해 일부 코드를 작성하는 것이 흥미로울 것이며 다른 사람들도 도움을 줄 것이라고 확신합니다. 제 생각에는 둘 다 강점과 약점이 있다는 것입니다. 제 목표는 실제 시나리오에서 피하거나 악용 할 수 있도록 정확히 무엇인지 알아내는 것입니다.


Mike Ash는 그의 포스트 "Performance Comparisons of Common Operations" 에서 다양한 Objective-C 메서드 호출과 C 및 C ++의 성능에 대한 몇 가지 어려운 수치를 가지고 있습니다 . 또한 Savoy Software 의이 게시물 은 Objective-C ++를 사용하여 iPhone 애플리케이션의 성능을 조정하는 데있어 흥미로운 읽기입니다.

저는 Objective-C ++보다 Objective-C의 명확하고 설명적인 구문을 선호하는 경향이 있으며 언어 자체가 성능 병목 현상의 원인이되는 것을 찾지 못했습니다. 나는 코드를 훨씬 더 유지 관리 할 수있게 만들면 약간의 성능을 희생하는 일을하는 경향이 있습니다.


예, 잘 작성된 C ++는 상당히 빠릅니다. 성능이 중요한 프로그램을 작성 중이고 C ++가 C만큼 빠르지 않거나 (또는 ​​몇 퍼센트 이내) 잘못된 것입니다. ObjC 구현이 C만큼 빠르다면 일반적으로 뭔가 잘못된 것입니다. 즉, 프로그램이 내부에서 작동하는 추상화 계층 (예 : 직접) 아래로 이동하기 위해 '더러운'트릭을 사용하기 때문에 ObjC OOD의 나쁜 예일 가능성이 높습니다. ivar 액세스.

Mike Ash '비교'는 매우 오해의 소지가 있습니다. 작성한 프로그램의 실행 시간을 비교하는 접근 방식을 권장하지 않으며 C 대 C ++ 대 ObjC를 비교하는 데 권장하지 않습니다. 제시된 결과는 컴파일러 최적화가 비활성화 된 테스트에서 제공됩니다 . 최적화가 비활성화 된 상태로 컴파일 된 프로그램은 실행 시간을 측정 할 때 거의 관련이 없습니다. C ++를 Objective-C와 비교하는 벤치 마크로 보는 것은 결함이 있습니다. 이 테스트는 또한 전체 실제 최적화 구현이 아닌 개별 기능을 비교합니다. 개별 기능은 두 언어와 매우 다른 방식으로 결합됩니다. 이는 최적화 된 구현을위한 현실적인 성능 벤치 마크와는 거리가 멀습니다. 예 : 최적화가 활성화 된 경우IMP캐시는 가상 함수 호출만큼 느립니다. 정적 디스패치 (예 :를 사용하는 동적 디스패치와 반대 virtual) 및 알려진 C ++ 유형에 대한 호출 (동적 디스패치가 우회 될 수 있음)은 적극적으로 최적화 될 수 있습니다. 이 과정을 devirtualization이라고하며, 사용시 선언되는 멤버 함수는 d virtual일 수도 있습니다 inline. 선언 virtual되고 빈 본문이있는 멤버 함수에 대해 많은 호출이 수행되는 Mike Ash 테스트의 경우 : 컴파일러가 구현을보고 동적 디스패치를 ​​결정할 수 있기 때문에 이러한 호출은 유형이 알려 지면 완전히 최적화됩니다. 불필요한. 컴파일러는 또한malloc최적화 된 빌드 (스택 스토리지 선호). 따라서 C, C ++ 또는 Objective-C에서 컴파일러 최적화를 활성화하면 실행 시간이 크게 달라질 수 있습니다.

제시된 결과가 완전히 쓸모 없다고 말하는 것은 아닙니다. 당신은 그들이에서 보내는 시간 사이에 측정 가능한 차이가 있는지 확인하려는 경우 외부 API에 대한 몇 가지 유용한 정보를 얻을 수 pthread_create또는 +[NSObject alloc]다른 대 하나의 플랫폼이나 아키텍처가. 물론이 두 예제는 테스트에서 최적화 된 구현을 사용합니다 (개발중인 경우가 아니면). 그러나 컴파일하는 프로그램에서 한 언어를 다른 언어와 비교하는 경우에는 최적화를 비활성화하면 제시된 결과가 쓸모가 없습니다.

개체 생성

ObjC에서 객체 생성도 고려하십시오. 모든 객체는 동적으로 할당됩니다 (예 : 힙에). C ++를 사용하면 스택 (예 : C 구조체를 생성하고 많은 경우에 간단한 함수를 호출하는 것만 큼 빠름), 힙 또는 추상 데이터 유형의 요소로 객체를 생성 할 수 있습니다. 할당하고 해제 할 때마다 (예 : malloc / free를 통해) 잠금을 도입 할 수 있습니다. 스택에 C 구조체 또는 C ++ 객체를 만들 때 잠금이 필요하지 않으며 (내부 멤버가 힙 할당을 사용할 수 있음) 종종 몇 개의 명령어 또는 몇 개의 명령어와 함수 호출이 필요합니다.

또한 ObjC 객체는 참조 횟수 인스턴스입니다. 객체가 std::shared_ptr성능에 중요한 C ++가 되기위한 실제 필요성 은 매우 드뭅니다. 모든 인스턴스를 공유 참조 계산 인스턴스로 만드는 것이 C ++에서 필요하거나 바람직하지 않습니다. C ++로 소유권과 수명을 훨씬 더 많이 제어 할 수 있습니다.

배열 및 컬렉션

C 및 C ++의 배열과 많은 컬렉션도 강력한 형식의 컨테이너와 연속 메모리를 사용합니다. 다음 요소의 멤버 주소가 종종 알려져 있기 때문에 최적화 프로그램은 훨씬 더 많은 작업을 수행 할 수 있으며 캐시 및 메모리 지역성이 우수합니다. ObjC를 사용하면 표준 개체 (예 :)의 현실과는 거리가 멀습니다 NSObject.

급파

메서드와 관련하여 많은 C ++ 구현은 특히 고도로 최적화 된 프로그램에서 가상 / 동적 호출을 거의 사용하지 않습니다. 이들은 옵티 마이저를위한 정적 메서드 호출 및 사료입니다.

ObjC 메서드를 사용하면 각 메서드 호출 (objc 메시지 전송)이 동적이며 결과적으로 최적화 프로그램의 방화벽이됩니다. 궁극적으로 성능에 중요한 ObjC를 작성할 때 성능을 최소한으로 유지하기 위해 할 수있는 작업과 할 수없는 작업에 대한 많은 제한 또는 불편을 초래합니다. 이로 인해 더 큰 메서드, IMP 캐싱, C의 빈번한 사용이 발생할 수 있습니다.

일부 실시간 응용 프로그램을 사용할 수 있는 자신의 렌더링 경로에서 ObjC 메시지를. 없음-오디오 렌더링이 이에 대한 좋은 예입니다. ObjC 디스패치는 단순히 실시간 목적으로 설계되지 않았습니다. 객체를 메시징 할 때 배후에서 할당 및 잠금이 발생할 수 있으므로 objc 메시징의 복잡성 / 시간을 예측할 수 없어 오디오 렌더링이 마감일을 놓칠 수 있습니다.

다른 기능들

C ++는 또한 많은 라이브러리에 대한 제네릭 / 템플릿 구현을 제공합니다. 이들은 매우 잘 최적화됩니다. 형식이 안전하며 템플릿으로 많은 인라인 및 최적화를 수행 할 수 있습니다 (컴파일시 발생하는 다형성, 최적화 및 특수화를 고려하십시오). C ++는 엄격한 ObjC에서 사용할 수 없거나 비교할 수없는 여러 기능을 추가합니다. 매우 다른 언어, 객체 및 라이브러리를 직접 비교하는 것은 그다지 유용하지 않습니다. 실제 실현의 매우 작은 부분 집합입니다. 설계 및 구현의 여러 측면을 고려하여 질문을 라이브러리 / 프레임 워크 또는 실제 프로그램으로 확장하는 것이 좋습니다.

기타 포인트

C 및 C ++ 기호는 빌드의 다양한 단계 (스트리핑, 데드 코드 제거, 인라인 및 초기 인라인, 링크 시간 최적화)에서보다 쉽게 ​​제거하고 최적화 할 수 있습니다. 이것의 이점으로는 바이너리 크기 감소, 시작 /로드 시간 감소, 메모리 소비 감소 등이 있습니다. 단일 앱의 경우 그렇게 큰 문제가 아닐 수 있습니다. 하지만 많은 코드를 재사용해야하고 그렇게해야한다면 ObjC를 구현하면 공유 라이브러리가 프로그램에 불필요한 가중치를 많이 추가 할 수 있습니다. 따라서 확장 성과 재사용은 중대형 프로젝트와 재 사용률이 높은 그룹의 요소이기도합니다.

포함 된 라이브러리

ObjC 라이브러리 구현자는 또한 환경에 맞게 최적화하므로 라이브러리 구현자는 일부 언어 및 환경 기능을 사용하여 최적화 된 구현을 제공 할 수 있습니다. 순수 ObjC에서 최적화 된 프로그램을 작성할 때 상당히 중요한 제한이 있지만 Cocoa에는 고도로 최적화 된 구현이 존재합니다. 이것은 C ++ 표준 라이브러리 (일부 사람들이 STL이라고 부르는 것)도 부끄럽지 않지만 Cocoa의 강점 중 하나입니다. Cocoa는 C ++보다 훨씬 더 높은 수준의 추상화에서 작동합니다.하고있는 작업 (또는해야하는 작업)을 잘 모르는 경우 금속에 더 가깝게 작동하면 실제로 비용이 발생할 수 있습니다.. Falling back on to a good library implementation if you are not an expert in some domain is a good thing, unless you are really prepared to learn. As well, Cocoa's environments are limited; you can find implementations/optimizations which make better use of the OS.

If you're writing optimized programs and have experience doing so in both C++ and ObjC, clean C++ implementations will often be twice as fast or faster than clean ObjC (yes, you can compare against Cocoa). If you know how to optimize, you can often do better than higher level, general purpose abstractions. Although, some optimized C++ implementations will be as fast as or slower than Cocoa's (e.g. my initial attempt at file I/O was slower than Cocoa's -- primarily because the C++ implementation initializes its memory).

A lot of it comes down to the language features you are familiar with. I use both langs, they both have different strengths and models/patterns. They complement each other quite well, and there are great libraries for both. If you're implementing a complex, performance critical program, correct use of C++'s features and libraries will give you much more control and provide significant advantages for optimization, such that in the right hands, "several times faster" is a good default expectation (don't expect to win every time, or without some work, however). Remember, it takes years to understand C++ well enough to really reach that point.

I keep the majority of my performance critical paths as C++, but also recognize that ObjC is also a very good solution for some problems, and that there are some very good libraries available.


It's very hard to collect "hard data" for this that's not misguiding.

The biggest problem with doing a feature-to-feature comparison like you suggest is that the two languages encourage very different coding styles. Objective-C is a dynamic language with duck typing, where typical C++ usage is static. The same object-oriented architecture problem would likely have very different ideal solutions using C++ or Objective-C.

My feeling (as I have programmed much in both languages, mostly on huge projects): To maximize Objective-C performance, it has to be written very close to C. Whereas with C++, it's possible to make much more use of the language without any performance penalty compared to C.

Which one is better? I don't know. For pure performance, C++ will always have the edge. But the OOP style of Objective-C definitely has its merits. I definitely think it is easier to keep a sane architecture with it.


This really isn't something that can be answered in general as it really depends on how you use the language features. Both languages will have things that they are fast at, things that they are slow at, and things that are sometimes fast and sometimes slow. It really depends on what you use and how you use it. The only way to be certain is to profile your code.

In Objective C you can also write c++ code, so it might be easier to code in Objective C for the most part, and if you find something that doesn't perform well in it, then you can have a go at writting a c++ version of it and seeing if that helps (C++ tends to optimize better at compile time). Objective C will be easier to use if APIs you are interfacing with are also written in it, plus you might find it's style of OOP is easier or more flexible.

In the end, you should go with what you know you can write safe, robust code in and if you find an area that needs special attention from the other language, then you can swap to that. X-Code does allow you to compile both in the same project.


I have a couple of tests I did on an iPhone 3G almost 2 years ago, there was no documentation or hard numbers around in those days. Not sure how valid they still are but the source code is posted and attached.

This isn't a very extensive test, I was mainly interested in NSArray vs C Array for iterating a large number of objects.

http://memo.tv/nsarray_vs_c_array_performance_comparison

http://memo.tv/nsarray_vs_c_array_performance_comparison_part_ii_makeobjectsperformselector

You can see the C Array is much faster at high iterations. Since then I've realized that the bottleneck is probably not the iteration of the NSArray but the sending of the message. I wanted to try methodForSelector and calling the methods directly to see how big the difference would be but never got round to it. According to Mike Ash's benchmarks it's just over 5x faster.


I don't have hard data for Objective C, but I do have a good place to look for C++.

C++ started as C with Classes according to Bjarne Stroustroup in his reflection on the early years of C++ (http://www2.research.att.com/~bs/hopl2.pdf), so C++ can be thought of (like Objective C) as pushing C to its limits for object orientation.

What are those limits? In the 1994-1997 time frame, a lot of researchers figured out that object-orientation came at a cost due to dynamic binding, e.g. when C++ functions are marked virtual and there may/may not be children classes that override these functions. (In Java and C#, all functions expect ctors are inherently virtual, and there isnt' much you can do about it.) In "A Study of Devirtualization Techniques for a Java Just-In-Time Compiler" from researchers at IBM Research Tokyo, they contrast the techniques used to deal with this, including one from Urz Hölzle and Gerald Aigner. Urz Hölzle, in a separate paper with Karel Driesen, had shown that on average 5.7% of time in C++ programs (and up to ~50%) was spent in calling virtual functions (e.g. vtables + thunks). He later worked with some Smalltalk researachers in what ended up the Java HotSpot VM to solve these problems in OO. Some of these features are being backported to C++ (e.g. 'protected' and Exception handling).

As I mentioned, C++ is static typed where Objective C is duck typed. The performance difference in execution (but not lines of code) probably is a result of this difference.


This study says to really get the performance in a CPU intensive game, you have to use C. The linked article is complete with a XCode project that you can run.

I believe the bottom line is: Use Objective-C where you must interact with the iPhone's functions (after all, putting trampolines everywhere can't be good for anyone), but when it comes to loops, things like vector object classes, or intensive array access, stick with C++ STL or C arrays to get good performance.

I mean it would be totally silly to see position = [[Vector3 alloc] init] ;. You're just asking for a performance hit if you use references counts on basic objects like a position vector.


yes. c++ reign supreme in performance/expresiveness/resource tradeoff.

"I'm looking for hard data, not evangelism". google is your best friend.

  1. obj-c nsstring is swapped with c++'s by apple enginneers for performance. in a resource constrained devices, only c++ cuts it as a MAINSTREAM oop language. NSString stringWithFormat is slow

  2. obj-c oop abstraction is deconstructed into procedural-based c-structs for performance, otherwise a MAGNITUDE order slower than java! the author is also aware of message caching - yet no-go. so modeling lots of small players/enemies objects is done in oop with c++ or else, lots of Procedural structs with a simple OOP wrapper around it with obj-c. there can be one paradigm that equates Procedural + Object-Oriented Programming = obj-c. http://ejourneyman.wordpress.com/2008/04/23/writing-a-ray-tracer-for-cocoa-objective-c/

참고URL : https://stackoverflow.com/questions/926728/will-my-iphone-app-take-a-performance-hit-if-i-use-objective-c-for-low-level-cod

반응형