Следующий код, который сопоставляет простые носители значений с логическими значениями, быстрее работает на Java быстрее, чем Swift 2 - XCode 7 beta3, "Быстрая, агрессивная оптимизация [-Ofast]" и "Быстрая оптимизация всего модуля", Я могу получить более 280 м поисков/сек в Java, но только около 10 М в Swift.
Когда я смотрю на него в "Инструментах", я вижу, что большую часть времени идет в пару вызовов сохранения/освобождения, связанных с поиском карты. Любые предложения о том, почему это происходит или обходной путь, будут оценены.
Структура кода представляет собой упрощенную версию моего реального кода, который имеет более сложный класс ключей, а также хранит другие типы (хотя для меня является фактическим для Boolean). Также обратите внимание, что я использую один экземпляр изменяемого ключа для извлечения, чтобы избежать выделения объектов внутри цикла, и, согласно моим тестам, это быстрее в Swift, чем неизменяемый ключ.
EDIT: Я также попытался переключиться на NSMutableDictionary, но при использовании с объектами Swift в качестве ключей это кажется очень медленным.
EDIT2: я попытался выполнить тест в objc (который не имел бы дополнительных служебных служебных данных), и он быстрее, но все же на порядок медленнее, чем Java... Я собираюсь представить этот пример как еще один вопрос, чтобы увидеть, есть ли у кого-нибудь идеи.
EDIT3 - Ответ. Я опубликовал свои выводы и свое обходное решение в ответе ниже.
public final class MyKey : Hashable {
var xi : Int = 0
init( _ xi : Int ) { set( xi ) }
final func set( xi : Int) { self.xi = xi }
public final var hashValue: Int { return xi }
}
public func == (lhs: MyKey, rhs: MyKey) -> Bool {
if ( lhs === rhs ) { return true }
return lhs.xi==rhs.xi
}
...
var map = Dictionary<MyKey,Bool>()
let range = 2500
for x in 0...range { map[ MyKey(x) ] = true }
let runs = 10
for _ in 0...runs
{
let time = Time()
let reps = 10000
let key = MyKey(0)
for _ in 0...reps {
for x in 0...range {
key.set(x)
if ( map[ key ] == nil ) { XCTAssertTrue(false) }
}
}
print("rate=\(time.rate( reps*range )) lookups/s")
}
и вот соответствующий код Java:
public class MyKey {
public int xi;
public MyKey( int xi ) { set( xi ); }
public void set( int xi) { this.xi = xi; }
@Override public int hashCode() { return xi; }
@Override
public boolean equals( Object o ) {
if ( o == this ) { return true; }
MyKey mk = (MyKey)o;
return mk.xi == this.xi;
}
}
...
Map<MyKey,Boolean> map = new HashMap<>();
int range = 2500;
for(int x=0; x<range; x++) { map.put( new MyKey(x), true ); }
int runs = 10;
for(int run=0; run<runs; run++)
{
Time time = new Time();
int reps = 10000;
MyKey buffer = new MyKey( 0 );
for (int it = 0; it < reps; it++) {
for (int x = 0; x < range; x++) {
buffer.set( x );
if ( map.get( buffer ) == null ) { Assert.assertTrue( false ); }
}
}
float rate = reps*range/time.s();
System.out.println( "rate = " + rate );
}