JQuery найдет все идентификаторы, начинающиеся со строки?

Меня заинтересовал этот небольшой пример алгоритма на Python для перебора большого списка слов. Я пишу несколько «инструментов», которые позволят мне разрезать строку или массив Objective-C аналогично Python.

В частности, это элегантное решение привлекло мое внимание тем, что оно выполняется очень быстро, и в нем в качестве ключевого элемента алгоритма используется фрагмент строки. Попробуй решить это без кусочка!

Я воспроизвел свою локальную версию, используя список слов Moby ниже. Вы можете использовать / usr / share / dict / words , если вам не хочется загружать Moby. Источник - это просто большой словарный список уникальных слов.

#!/usr/bin/env python

count=0
words = set(line.strip() for line in   
           open("/Users/andrew/Downloads/Moby/mwords/354984si.ngl"))
for w in words:
    even, odd = w[::2], w[1::2]
    if even in words and odd in words:
        count+=1

print count      

Этот сценарий будет а) интерпретироваться Python; б) прочитать файл словаря Moby объемом 4,1 МБ, 354 983 слова; в) зачистите линии; г) поместить линии в набор, и; д) и найти все комбинации, в которых числа и вероятность данного слова также являются словами. На MacBook Pro это выполняется примерно за 0,73 секунды.

Я попытался переписать ту же программу на Objective-C. Я новичок в этом языке, поэтому не торопитесь, но, пожалуйста, укажите на ошибки.

#import 

NSString *sliceString(NSString *inString, NSUInteger start, NSUInteger stop, 
        NSUInteger step){
    NSUInteger strLength = [inString length];

    if(stop > strLength) {
        stop = strLength;
    }

    if(start > strLength) {
        start = strLength;
    }

    NSUInteger capacity = (stop-start)/step;
    NSMutableString *rtr=[NSMutableString stringWithCapacity:capacity];    

    for(NSUInteger i=start; i < stop; i+=step){
        [rtr appendFormat:@"%c",[inString characterAtIndex:i]];
    }
    return rtr;
}

NSSet * getDictWords(NSString *path){

    NSError *error = nil;
    NSString *words = [[NSString alloc] initWithContentsOfFile:path
                         encoding:NSUTF8StringEncoding error:&error];
    NSCharacterSet *sep=[NSCharacterSet newlineCharacterSet];
    NSPredicate *noEmptyStrings = 
                     [NSPredicate predicateWithFormat:@"SELF != ''"];

    if (words == nil) {
        // deal with error ...
    }
    // ...

    NSArray *temp=[words componentsSeparatedByCharactersInSet:sep];
    NSArray *lines = 
        [temp filteredArrayUsingPredicate:noEmptyStrings];

    NSSet *rtr=[NSSet setWithArray:lines];

    NSLog(@"lines: %lul, word set: %lul",[lines count],[rtr count]);
    [words release];

    return rtr;    
}

int main (int argc, const char * argv[])
{
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];

    int count=0;

    NSSet *dict = 
       getDictWords(@"/Users/andrew/Downloads/Moby/mwords/354984si.ngl");

    NSLog(@"Start");

    for(NSString *element in dict){
        NSString *odd_char=sliceString(element, 1,[element length], 2);
        NSString *even_char=sliceString(element, 0, [element length], 2);
        if([dict member:even_char] && [dict member:odd_char]){
            count++;
        }

    }    
    NSLog(@"count=%i",count);

    [pool drain];
    return 0;
}

Версия Objective-C дает тот же результат (13 341 слово), но это занимает почти 3 секунды. Я должен делать что-то ужасно неправильное, чтобы скомпилированный язык был более чем в 3 раза медленнее, чем язык сценариев, но будь я проклят, если смогу понять, почему.

Основной алгоритм тот же: прочтите строки, удалите их и сложите в набор.

Я предполагаю, что медленным является обработка элементов NSString, но я не знаю альтернативы.

Править

Я отредактировал Python следующим образом:

#!/usr/bin/env python
import codecs
count=0
words = set(line.strip() for line in 
     codecs.open("/Users/andrew/Downloads/Moby/mwords/354984si.ngl",
          encoding='utf-8'))
for w in words:
    if w[::2] in words and w[1::2] in words:
        count+=1

print count 

Чтобы UTF-8 находился в той же плоскости, что и UTF-8 NSString. Это замедлило работу Python до 1,9 секунды.

Я также переключаю тест среза на тип короткого замыкания, как предлагал как для версии Python, так и для версии obj-c. Теперь они близки к одинаковой скорости. Я также пробовал использовать массивы C, а не NSStrings, и это было намного быстрее, но не так просто. При этом вы также теряете поддержку utf-8.

Python действительно крут ...

Edit 2

Я обнаружил узкое место, которое значительно ускорило работу. Вместо использования метода [rtr appendFormat: @ "% c", [inString characterAtIndex: i]]; для добавления символа в возвращаемую строку я использовал следующее:

for(NSUInteger i=start; i < stop; i+=step){
    buf[0]=[inString characterAtIndex:i];
    [rtr appendString:[NSString stringWithCharacters:buf length:1]];
}

Теперь я могу finally утверждают, что версия Objective-C быстрее, чем версия Python, но ненамного.

18
задан Community 23 May 2017 в 11:53
поделиться