В чем разница между использованием CGFloat и float?
Я, как правило, использую CGFloat повсюду, но мне интересно, получаю ли я бессмысленный "хит производительности" с этим. CGFloat кажется чем-то" тяжелее", чем float, верно? В какие моменты я должен использовать CGFloat, и что действительно имеет значение?
4 ответов
как заявил @weichsel, CGFloat-это просто typedef для любого float
или double
. Вы можете увидеть сами по команде-дважды щелкнув по "CGFloat" в Xcode - он перейдет к CGBase.H заголовок, в котором определяется typedef. Такой же подход используется для NSInteger и NSUInteger.
эти типы были введены, чтобы упростить написание кода, который работает как на 32-разрядных, так и на 64-разрядных без изменений. Однако, если все, что вам нужно-это float
точность в пределах вашего собственного код, вы все еще можете использовать float
Если хотите - это несколько уменьшит объем вашей памяти. То же самое касается целочисленных значений.
Я предлагаю вам инвестировать скромное время, необходимое для того, чтобы сделать ваше приложение 64-битным и попытаться запустить его как таковое, поскольку большинство Mac теперь имеют 64-битные процессоры, а Snow Leopard полностью 64-бит, включая ядро и пользовательские приложения. 64-разрядное руководство по переходу для Cocoa является полезным ресурсом.
CGFloat-обычный поплавок в 32-разрядных системах и дважды на 64-битных системах
typedef float CGFloat;// 32-bit
typedef double CGFloat;// 64-bit
таким образом, вы не получите никакого штрафа за производительность.
Как говорили другие, CGFloat-это поплавок на 32-битных системах и двойной на 64-битных системах. Однако решение об этом было унаследовано от OS X, где оно было принято на основе характеристик производительности ранних процессоров PowerPC. Другими словами, вы не должны думать, что float для 32-разрядных процессоров и double для 64-разрядных процессоров. (Я считаю, что процессоры ARM от Apple смогли обрабатывать двойники задолго до того, как они стали 64-битными.) Основной хит производительности использования двойников заключается в том, что они используют дважды памяти и поэтому может быть медленнее, если вы делаете много операций с плавающей точкой.
С
из исходного кода Foundation, в CoreGraphics' CGBase.h
:
/* Definition of `CGFLOAT_TYPE', `CGFLOAT_IS_DOUBLE', `CGFLOAT_MIN', and
`CGFLOAT_MAX'. */
#if defined(__LP64__) && __LP64__
# define CGFLOAT_TYPE double
# define CGFLOAT_IS_DOUBLE 1
# define CGFLOAT_MIN DBL_MIN
# define CGFLOAT_MAX DBL_MAX
#else
# define CGFLOAT_TYPE float
# define CGFLOAT_IS_DOUBLE 0
# define CGFLOAT_MIN FLT_MIN
# define CGFLOAT_MAX FLT_MAX
#endif
/* Definition of the `CGFloat' type and `CGFLOAT_DEFINED'. */
typedef CGFLOAT_TYPE CGFloat;
#define CGFLOAT_DEFINED 1
Copyright (c) 2000-2011 Apple Inc.
это по сути дела:
#if defined(__LP64__) && __LP64__
typedef double CGFloat;
#else
typedef float CGFloat;
#endif
здесь __LP64__
указывает, является ли текущая архитектура* 64-разрядная.
обратите внимание, что 32-разрядные системы все еще могут использовать 64-разрядный double
, это просто занимает больше времени процессора, поэтому CoreGraphics делает это для оптимизационные цели, не для совместимости. Если вы не беспокоитесь о производительности, но беспокоитесь о точности, просто используйте double
.
Свифт
В Swift, CGFloat
это struct
обертка вокруг либо Float
на 32-разрядных архитектурах или Double
на 64-битных (вы можете обнаружить это во время выполнения или компиляции с помощью CGFloat.NativeType
)
из исходного кода CoreGraphics,in CGFloat.swift.gyb
:
public struct CGFloat {
#if arch(i386) || arch(arm)
/// The native type used to store the CGFloat, which is Float on
/// 32-bit architectures and Double on 64-bit architectures.
public typealias NativeType = 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.
public typealias NativeType = Double
#endif
*в частности, long
s и указатели, следовательно,LP
. См. также:http://www.unix.org/version2/whatsnew/lp64_wp.html