Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

(Edit) I wrote same code with Swift and C lang(Find Prime number), but C lang is much faster then Swift

(There has some Edit in below)
Well, I wrote exactly the same code with Swift and C lang. It’s a code to find a Prime number and show that.
I expect that Swift lang’s Code is much faster than C lang’s program, but It doesn’t.

Is there any reason Swift lang is much slower than C lang code?

When I found until 4000th Prime number, C lang finished calculating with only one second.
But, Swift finished with 38.8 seconds.
It’s much much slower than I thought.

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

Here is a code I wrote.

Do there any solutions to fast up Swift’s code?
(Sorry for the Japanese comment or text in the code.)

Swift

import CoreFoundation
/*
var calendar = Calendar.current
calender.locale = .init(identifier: "ja.JP")
*/

var primeCandidate: Int
var prime: [Int] = []

var countMax: Int

print("いくつ目まで?(最小2、最大100000まで)\n→ ", terminator: "")

countMax = Int(readLine()!)!

var flagPrint: Int

print("表示方法を選んでください。(1:全て順番に表示、2:\(countMax)番目の一つだけ表示)\n→ ", terminator: "")
flagPrint = Int(readLine()!)!

prime.append(2)
prime.append(3)

var currentMaxCount: Int = 2
var numberCount: Int

primeCandidate = 4

var flag: Int = 0
var ix: Int

let startedTime = clock()
//let startedTime = time()
//.addingTimeInterval(0.0)

while currentMaxCount < countMax {
    for ix in 2..<primeCandidate {
        if primeCandidate % ix == 0 {
            flag = 1
            break
        }
    }
    
    if flag == 0 {
        prime.append(primeCandidate)
        currentMaxCount += 1
    } else if flag == 1 {
        flag = 0
    }
    
    primeCandidate += 1
}

let endedTime = clock()
//let endedTime = Time()
//.timeIntervalSince(startedTime)

if flagPrint == 1 {
    print("計算された素数の一覧:", terminator: "")
    
    let completedPrimeNumber = prime.map {
        $0
    }
    
    
    print(completedPrimeNumber)
    //print("\(prime.map)")
    
    print("\n\n終わり。")
    
} else if flagPrint == 2 {
    print("\(currentMaxCount)番目の素数は\(prime[currentMaxCount - 1])です。")
}

print("\(countMax)番目の素数まで計算。")
print("計算経過時間: \(round(Double((endedTime - startedTime) / 100000)) / 10)秒")

Clang

#include <stdio.h>
#include <time.h> //経過時間計算のため

int main(void)
{
    int primeCandidate;
    unsigned int prime[100000];
    
    int countMax;
    
    printf("いくつ目まで?(最小2、最大100000まで)\n→ ");
    scanf("%d", &countMax);
    
    int flagPrint;
    
    printf("表示方法を選んでください。(1:全て順番に表示、2:%d番目の一つだけ表示)\n→ ", countMax);
    scanf("%d", &flagPrint);
    
    prime[0] = 2;
    prime[1] = 3;
    
    int currentMaxCount = 2;
    int numberCount;
    
    primeCandidate = 4;
    
    int flag = 0;
    
    int ix;
    
    int startedTime = time(NULL);
    for(;currentMaxCount < countMax;primeCandidate++){
        /*
        for(numberCount = 0;numberCount < currentMaxCount - 1;numberCount++){
            if(primeCandidate % prime[numberCount] == 0){
                flag = 1;
                break;
            }
        }
            */
            
        for(ix = 2;ix < primeCandidate;++ix){
            if(primeCandidate % ix == 0){
                flag = 1;
                break;
            }
        }
            
        if(flag == 0){
            prime[currentMaxCount] = primeCandidate;
            currentMaxCount++;
        } else if(flag == 1){
            flag = 0;
        }
    }
    int endedTime = time(NULL);
    
    if(flagPrint == 1){
        printf("計算された素数の一覧:");
        for(int i = 0;i < currentMaxCount - 1;i++){
            printf("%d, ", prime[i]);
        }
        printf("%d.\n\n終わり", prime[currentMaxCount - 1]);
    } else if(flagPrint == 2){
        printf("%d番目の素数は「%d」です。\n",currentMaxCount ,prime[currentMaxCount - 1]);
    }
    
    printf("%d番目の素数まで計算", countMax);
    printf("計算経過時間: %d秒\n", endedTime - startedTime);
    
    return 0;
}

**Add**

I found some reason for one.

for ix in 0..<currentMaxCount - 1 {
        if primeCandidate % prime[ix] == 0 {
            flag = 1
            break
        }
    }

I wrote a code to compare all numbers. That was a mistake.
But, I fix with code with this, also Swift finished calculating in 4.7 secs.
It’s 4 times slower than C lang also.

>Solution :

As with most of these "why does this same program in 2 different languages perform differently?", the answer is almost always: "because they’re not the same program."

They might be similar in high-level intent, but they’re implemented differently enough that you can distinguish their performance.

Sometimes they’re different in ways you can control (e.g. you use an array in one program and a hash set in the other) or sometimes in ways you can’t (e.g. you’re using CPython and you’re experiencing the overhead of interpretation and dynamic method dispatch, as compared to compiled C function calls).

In this case, there’s a few notable differences I can see:

  1. The prime array in your C code uses unsigned int, which is typically akin to UInt32. Your Swift code uses Int, which is typically equivalent to Int64. It’s twice the size, which doubles memory usage and decreases the efficacy of the CPU cache.
  2. Your C code pre-allocates the prime array on the stack, whereas your Swift code starts with an empty Array, and repeatedly grows it as necessary.
  3. Your C code doesn’t pre-initialize the contents of the prime array. Any junk that might be leftover in the memory is still there to be observed, whereas the Swift code will zero-out all the array memory before use.
  4. All Swift arithmetic operations are checked for overflow. This introduces a branch within every single +, %, etc. That’s good for program safety (overflow bugs will never be silent and will always be detected), but sub-optimal in performance-critical code where you’re certain that overflow is impossible. There’s non-checked variants of all the operators that you can use, such as &+, &-, etc.
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading