Apa perbedaan antara menggunakan CGFloat dan float?
169
Saya cenderung menggunakan CGFloat di mana-mana, tetapi saya ingin tahu apakah saya mendapatkan "kinerja yang tidak masuk akal" dengan ini. CGFloat tampaknya menjadi sesuatu yang "lebih berat" daripada float, bukan? Di titik mana saya harus menggunakan CGFloat, dan apa yang membuat perbedaan?
Seperti yang dikatakan @weichsel, CGFloat hanyalah sebuah typedef untuk salah satu floatatau double. Anda dapat melihat sendiri dengan mengklik ganda Command pada "CGFloat" di Xcode - itu akan melompat ke header CGBase.h di mana typedef didefinisikan. Pendekatan yang sama digunakan untuk NSInteger dan NSUInteger juga.
Jenis ini diperkenalkan untuk membuatnya lebih mudah untuk menulis kode yang berfungsi pada 32-bit dan 64-bit tanpa modifikasi. Namun, jika semua yang Anda butuhkan adalah floatketepatan dalam kode Anda sendiri, Anda masih dapat menggunakannya floatjika Anda mau - itu akan mengurangi jejak memori Anda. Hal yang sama berlaku untuk nilai integer.
Saya sarankan Anda menginvestasikan waktu sederhana yang diperlukan untuk membuat aplikasi Anda 64-bit bersih dan coba jalankan seperti itu, karena sebagian besar Mac sekarang memiliki CPU 64-bit dan Snow Leopard sepenuhnya 64-bit, termasuk aplikasi kernel dan pengguna. Panduan Transisi 64-bit Apple untuk Kakao adalah sumber yang bermanfaat.
Saya rasa saya mengerti sekarang. Tapi di iPhone sepertinya tidak terlalu masalah, kan?
4
Di iPhone seperti yang kita tahu, tidak. Namun, selalu bijaksana untuk kode bukti masa depan, dan ini akan membuatnya lebih mudah untuk menggunakan kembali kode yang sama untuk OS X.
Quinn Taylor
jadi Anda mengatakan, pada dasarnya, JANGAN PERNAH menggunakan float atau double langsung sejak itu Anda akan terikat pada arsitektur prosesor (dan saya pikir JVM cepat diselesaikan tahun ini :)). Jadi primitif apa yang aman? int?
Dan Rosenstark
9
Saya tidak mengatakan TIDAK PERNAH menggunakan primitif secara langsung. Ada saat-saat primitif langsung dapat bermasalah, seperti jika variabel dapat digunakan untuk menyimpan data yang bisa meluap, seperti pada 64-bit. Secara umum, menggunakan typedef yang bergantung pada arsitektur lebih aman, karena kode itu cenderung meledak pada arsitektur yang berbeda. Namun, terkadang menggunakan tipe 32-bit bisa sepenuhnya aman dan menghemat memori Anda. Ukuran primitif mungkin kurang dari masalah dalam JVM, tetapi Obj-C dan C dikompilasi, dan mencampur 32 dan 64 bit perpustakaan dan kode memang bermasalah.
Quinn Taylor
1
@ QuinnTaylor dapatkah Anda memberikan contoh praktis tentang bagaimana float akan meluap sementara CGFloat tidak? Baik float dan CGFloat memiliki jumlah bit yang terbatas. Anda bisa meluap keduanya dengan perlu menyimpan lebih banyak bit daripada yang bisa mereka pegang.
Pwner
76
CGFloat adalah float reguler pada sistem 32-bit dan sistem 64-bit ganda
Nah, Anda menggunakan memori dua kali lebih banyak, jika Anda khawatir dengan memori.
Tyler
8
Hanya pada 64-bit.
Quinn Taylor
13
Benar, iPhone OS adalah 32-bit. Jika dipikir-pikir, iPhone tidak mendorong batasan RAM 4GB 32-bit, juga tidak menggunakan prosesor Intel (yang 64-bit lebih cepat dari 32-bit). Plus, itu menggunakan Modern Runtime (bukan Legacy Runtime 32-bit pada desktop - cari SO untuk istilah-istilah ini jika Anda penasaran) sehingga pada dasarnya dapat melakukan semuanya 64-bit OS X dapat. Mungkin suatu hari nanti kita akan melihat perangkat yang menjalankan OS iPhone dan 64-bit, tetapi saat ini tidak ada.
Quinn Taylor
23
Masukkan: iPhone 5S
dgund
7
5S sekarang dalam 64 bit, terakhir kali saya memasuki konferensi (london), mereka mengatakan cara mereka menjalankan aplikasi 32-bit pada ios7 adalah dengan memasukkan kumpulan cache bersama lainnya dalam memori, yang dapat menghasilkan penggunaan lebih banyak memori secara keseluruhan. jadi nilainya untuk mengkonversi semuanya hingga 64-bit. (kecuali jika Anda ingin mendukung 5.1+ atau 6.0+)
phil88530
2
Seperti yang orang lain katakan, CGFloat adalah pelampung pada sistem 32-bit dan sistem ganda pada 64-bit. Namun, keputusan untuk melakukan itu diwarisi dari OS X, di mana ia dibuat berdasarkan karakteristik kinerja CPU PowerPC awal. Dengan kata lain, Anda seharusnya tidak berpikir bahwa float untuk CPU 32-bit dan ganda untuk CPU 64-bit. (Saya percaya, prosesor ARM Apple mampu memproses ganda jauh sebelum 64-bit.) Kinerja utama dari penggunaan ganda adalah bahwa mereka menggunakan memori dua kali lipat dan karenanya mungkin lebih lambat jika Anda melakukan banyak operasi floating point. .
Di mana __LP64__menunjukkan apakah arsitektur saat ini * adalah 64-bit.
Perhatikan bahwa sistem 32-bit masih dapat menggunakan 64-bit double, hanya membutuhkan lebih banyak waktu prosesor, jadi CoreGraphics melakukan ini untuk keperluan optimasi, bukan untuk kompatibilitas. Jika Anda tidak khawatir tentang kinerja tetapi khawatir tentang akurasi, cukup gunakan double.
Cepat
Dalam Swift, CGFloatadalah structpembungkus baik Floatpada arsitektur 32-bit atau Doublepada yang 64-bit (Anda dapat mendeteksi ini saat run-atau compile-time dengan CGFloat.NativeType)
publicstructCGFloat{#ifarch(i386)||arch(arm)/// The native type used to store the CGFloat, which is Float on
/// 32-bit architectures and Double on 64-bit architectures.
publictypealiasNativeType=Float#elseif arch(x86_64)||arch(arm64)/// The native type used to store the CGFloat, which is Float on
/// 32-bit architectures and Double on 64-bit architectures.
publictypealiasNativeType=Double#endif
publicstructCGFloat{/// The native type used to store the CGFloat, which is Float on/// 32-bit architectures and Double on 64-bit architectures.public typealias NativeType=Double
int
?CGFloat adalah float reguler pada sistem 32-bit dan sistem 64-bit ganda
Jadi Anda tidak akan mendapatkan penalti kinerja.
sumber
Seperti yang orang lain katakan, CGFloat adalah pelampung pada sistem 32-bit dan sistem ganda pada 64-bit. Namun, keputusan untuk melakukan itu diwarisi dari OS X, di mana ia dibuat berdasarkan karakteristik kinerja CPU PowerPC awal. Dengan kata lain, Anda seharusnya tidak berpikir bahwa float untuk CPU 32-bit dan ganda untuk CPU 64-bit. (Saya percaya, prosesor ARM Apple mampu memproses ganda jauh sebelum 64-bit.) Kinerja utama dari penggunaan ganda adalah bahwa mereka menggunakan memori dua kali lipat dan karenanya mungkin lebih lambat jika Anda melakukan banyak operasi floating point. .
sumber
Objektif-C
Dari kode sumber Foundation, dalam CoreGraphics '
CGBase.h
:Hak Cipta (c) 2000-2011 Apple Inc.
Ini pada dasarnya dilakukan:
Di mana
__LP64__
menunjukkan apakah arsitektur saat ini * adalah 64-bit.Perhatikan bahwa sistem 32-bit masih dapat menggunakan 64-bit
double
, hanya membutuhkan lebih banyak waktu prosesor, jadi CoreGraphics melakukan ini untuk keperluan optimasi, bukan untuk kompatibilitas. Jika Anda tidak khawatir tentang kinerja tetapi khawatir tentang akurasi, cukup gunakandouble
.Cepat
Dalam Swift,
CGFloat
adalahstruct
pembungkus baikFloat
pada arsitektur 32-bit atauDouble
pada yang 64-bit (Anda dapat mendeteksi ini saat run-atau compile-time denganCGFloat.NativeType
)Dari kode sumber CoreGraphics, di
CGFloat.swift.gyb
:* Khususnya,
long
s dan pointer, makaLP
. Lihat juga: http://www.unix.org/version2/whatsnew/lp64_wp.htmlsumber
sebutkan saja - Jan, 2020 Xcode 11.3 / iOS13
Cepat 5
Dari kode sumber CoreGraphics
sumber