2012-07-05 84 views
0

一旦我写了一段python代码来进行反演的计算。将python代码转换为c代码很难吗?

只是为了好玩加上想看看c是否真的比运行时语言快, 我在c中写了类似的python代码。

的Python代码只用了不到3秒的运行,

但我的C代码,花了大约8秒。

任何人都可以告诉我我在哪里做错了,我应该如何改变/改进我的C代码?

谢谢!

输入文件只是100000行的数字,不重复,从1到100000以随机顺序排列。

Python代码:

import time 

def lookup(arr, num): 
    lower=0 
    upper=len(arr)-1 
    while 1: 
     if arr[upper]==num: 
      return upper 
     mid=(upper+lower)/2 
     if arr[mid]==num: 
      return mid 
     elif arr[mid]<num: 
      lower=mid+1 
     else: 
      upper=mid 

def main(): 
    time.clock() 
    f=open("IntegerArray.txt", "r").read().strip().split('\n') 
    array=[int(i) for i in f] 
    array.reverse() 
    s=sorted(array) 
    v=0 
    while(array): 
     i=lookup(s, array.pop()) 
     v+=i 
     s.pop(i) 
    print v 
    print time.clock() 
    raw_input() 

main() 

C代码:

#include <stdio.h> 
#include <stdlib.h> 

#define limit 100000 

int comp(const void *, const void *); 
void inversion(int *, int *, int); 
int lookup(int *, int, int); 

int main(void){ 
    FILE *f = fopen("IntegerArray.txt", "r"); 
    int n=0, array[limit], copy[limit]; 
    while(n<limit){ 
     fscanf(f, "%d", array+n); 
     copy[n]=array[n]; 
     n++; 
    } 
    qsort(copy, limit, sizeof(int), comp); 
    // int i; 
    // for(i=limit-100;i<limit;i++)printf("%d %d\n", array[i], copy[i]); 
    inversion(array, copy, limit); 
    // getchar(); 
    return 0; 
} 

int comp(const void *a, const void *b){ 
    return (*(int*)a>*(int*)b)?1:-1; 
} 

void inversion(int *a, int *b, int n){ 
    int c=0, index; 
    unsigned int v=0; 
    while(c<n){ 
     // if(c%1000==0)printf("%d %d\n", c, b[n-c-1]); 
     index=lookup(b, *a, n-c); 
     v+=index; 
     if((n-c)/2<index) 
      for(;index<n-c-1;index++) 
       b[index]=b[index+1]; 
     else{ 
      for(;index>0;index--) 
       b[index]=b[index-1]; 
      b++; 
     } 
     a++; 
     c++; 
    } 
    printf("%u\n", v); 
} 

int lookup(int *arr, int num, int n){ 
    int lower=0, upper=n-1, mid; 
    // if(arr[upper]==num)return upper; 
    // if(arr[lower]==num)return lower; 
    while(1){ 
     // printf("%d %d %d\n", lower, upper, num); 
     mid=(lower+upper)/2; 
     // if(lower==upper && arr[mid]!=num){ 
     // printf("%d %d %d\n", lower, upper, num); 
     // exit(1); 
     // } 
     if(arr[mid]==num)return mid; 
     else if(arr[mid]<num) 
      lower=mid+1; 
     else 
      upper=mid; 
    } 
} 
+0

Timsort通常比quicksort快,但我怀疑这是* only *因素... –

+0

如果您使用的是GNU工具集,请尝试在程序中运行'gcov':首先使用'-fprofile-arcs编译 - ftest-coverage“,然后运行该程序,然后运行'gcov sourcefile.c' –

回答

2

在Python inversion,您有:

s.pop(i) 

而在C,您有:

if((n-c)/2<index) 
    for(;index<n-c-1;index++) 
     b[index]=b[index+1]; 
else{ 
    for(;index>0;index--) 
     b[index]=b[index-1]; 
    b++; 
} 

对我来说看起来很不一样。
我不认为Python通过复制所有元素来实现pop

+0

实际上并不确定。 Python的列表应该是动态调整大小的数组;你不能从一个数组中的任意位置移除一个项目,而不会随后移动所有后面的元素。这就是为什么从Python列表的* end *中追加和弹出的算法比从头或中插入/删除项目的算法更加高效。 – Ben

+0

'流行'洗牌剩下的元素来填补这个洞,所以从一开始就流行不好,但流行在最后很快 –

+0

是的,我检查了python文档,然后将我的python代码改为它现在的样子。我曾经有s.pop(0)的列表没有倒过来。它花了大约7秒。在我更改我的代码后,它花了不到3秒。这可能是一个问题,我的c模拟不是真的,只是希望一些python专家可以告诉我python列表是如何在幕后完成的。感谢大家! – prM