Swift:高性能字符串转换?

问题描述 投票:0回答:1

我有大约36000个文件,每个文件包含250个单词,并且我需要通过删除每个十进制字符并小写所有大写字符来转换每个单词。

我将读取的每个单词传递给一个函数,该函数返回修改后的单词,为了我以后将其编入索引。

问题在于,使用如此大量的字符,速度非常慢。

我一直在尝试对字符串进行迭代,像在C中一样操作Characters,使用ascii值,但是Swift对此很糟糕,需要始终从Characters重构Strings。

我附带了这小段代码,但是我在Swift中对这个精确主题的了解是为了找到更好的方法。另外,我正在使用Swift 4.2。

func processToken(token: String) -> String {
    var result = String()

    for ascii in token.utf8 {
        if ascii > 64 && ascii < 91 {
            result.append(String(UnicodeScalar(UInt8(ascii + 32))))
        }
        else if ascii > 96 && ascii < 123 {
            result.append(String(UnicodeScalar(UInt8(ascii))))
        }
    }
    return result
}
swift string nsstring
1个回答
0
投票

我写了一个应该很快的解决方案。这是一个大多数使用普通旧C的Objective-C函数。为什么使用C?因为我们肯定知道C运行时在做什么,这基本上是为内存提供超薄包装。另一方面,Swift运行时的许多底层细节是未知的,并且有充分的理由。但是,可以肯定地认为,Swift具有比普通C更高的性能开销。在这方面,击败C的唯一方法是直接进入汇编器或打开您选择的十六进制编辑器并键入您自己的操作码和操作数。别误会,出于多种原因,应该始终首选Swift,但是如果性能至关重要,那么Objective-C / C是首选工具。

所以代码片段到了。它使用NSString并去除所有数字,并将所有大写字符转换为小写字母。

-  ( NSString* ) convert:( NSString* ) source
{
    const char bitmaskNonAsciiChar =  ( char ) ( 1 << 7 );
    const char* cSource = [ source UTF8String ];
    size_t strLength = strlen( cSource );
    size_t bufferSize = sizeof( char ) * strLength + 1;

    char *result = ( char* ) malloc( bufferSize );
    memset( result, '\0', bufferSize );

    int currentIndex = 0;
    for( int i = 0; i < strLength; ++i )
    {
        // Check if this is an UTF-8 character that's longer than one byte. If so, it can't be an ASCII character and we can just write this character to the result buffer.
        if( ( cSource[ i ] & bitmaskNonAsciiChar ) == bitmaskNonAsciiChar )
        {
            result[ currentIndex++ ] = cSource[ i ];
            continue;
        }

        // Now we know it is an ASCII character, so we need to check for digits and upper-case characters.
        if( cSource[ i ] >= ( char ) 46 && cSource[ i ] <= ( char ) 57 )
        {
            continue;
        }

        if( cSource[ i ] >= ( char ) 65 && cSource[ i ] <= ( char ) 90 )
        {
            result[ currentIndex++ ] = cSource[ i ] + ( char ) 32;
            continue;
        }

        // It's an ASCII character that is neither a digit nor upper-cased, so we just write it to the result buffer.
        result[ currentIndex++ ] = cSource[ i ];
    }

    NSString *resultString = [ NSString stringWithUTF8String: result ];
    free( result );

    return resultString;
}

© www.soinside.com 2019 - 2024. All rights reserved.