任何人都可以进一步提高...... [英] Can anyone improve this any further......

查看:53
本文介绍了任何人都可以进一步提高......的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在为一种语言编写一个字节码解释器/模拟器,

专门使用字符串作为变量(即所有变量都被推送到

堆栈作为字符串) 。因此,对于算术运算,我需要将
转换为32位整数,执行算术运算,然后将其转换回字符串,然后再将其转换回堆栈。

这可能每秒发生数百万次,因此我必须优化(用于速度)atol()和ltoa()函数。

。 />

这是我对ltoa()的尝试...(__ fastcall关键字是告诉我的

编译器通过寄存器传递参数,而不是使用内联

,因为它似乎同样快,并且这个函数从

各种模块调用..)。


静态字符* __fastcall myltoa(long n,char * s)

{

寄存器长r,k;

寄存器int flag = 0;

注册int next;


next = 0;

if(n == 0){

s [ next ++] =''0'';

}

else {

if(n< 0){

s [next ++] = '' - ';;

n = -n;

}


if(n< 100)goto label2;

if(n< 100000)goto label1;


k = 1000000000;

r = n / k ;

if(flag)s [next ++] =''0''+ r;

else if(r> 0){s [next ++] ='' 0''+ r; flag = 1;}

n - = r * k;


k = 100000000;

r = n / k;

if(flag)s [next ++] =''0''+ r;

else if(r> 0){s [next ++] = ''0''+ r; flag = 1;}

n - = r * k;


k = 10000000;

r = n / k;

if(flag)s [next ++] =''0''+ r;

else if(r> 0){s [next ++ ] =''0''+ r; flag = 1;}

n - = r * k;


k = 1000000;

r = n / k;

if(flag)s [next ++] =''0''+ r;

else if(r> 0){s [next ++] =''0''+ r; flag = 1;}

n - = r * k;


k = 100000;

r = n / k;

if(flag)s [next ++] =''0''+ r;

else if(r> 0) {s [next ++] =''0 ''+ r; flag = 1;}

n - = r * k;

label1:

k = 10000;

r = n / k;

if(flag)s [next ++] =''0''+ r;

else if(r> 0){s [next ++] =''0''+ r; flag = 1;}

n - = r * k;


k = 1000;

r = n / k;

if(flag)s [next ++] =''0''+ r;

else if(r > 0){s [next ++] =''0''+ r; flag = 1;}

n - = r * k;


k = 100;

r = n / k;

if(flag)s [next ++] =''0''+ r;

else if (r> 0){s [next ++] =''0''+ r; flag = 1;}

n - = r * k;

label2:

k = 10;

r = n / k;

if(flag)s [next ++] =''0''+ r;

else if(r> 0){s [next ++] =''0''+ r; flag = 1;}

n - = r * k;


r = n;

s [next ++] =''0''+ r;

}

s [下一页] =''\ 0'';

返回;

}

goto'是因为我认识到大多数数字是
小于100(主要是函数的返回代码)和那些不是
le超过100的ss往往小于100,000(这种语言通常不是用于数学化学的
)。这确实让我在一个紧凑的循环中获得了另外15到20%的速度提高了一些算术...


顺便说一下,我试过预计算所有字符串的整数值

压入堆栈(通过在字符串末尾的

堆栈上总是附加4字节整数值,但它实际上导致了因为

我必须对每个函数返回值或字符串连接执行atol()

操作,即使该值不会用于算术或

比较操作。


任何提示都会受到欢迎......


肖恩

I am writing a byte-code interpreter/emulator for a language that
exclusively uses strings for variables (i.e all variables are pushed onto
the stack as strings). Therefore for arithmetic operations I need to
convert the string to a 32 bit integer, carry out the arithmetic operation,
then convert it back to a string before pushing it back onto the stack.
This can happen millions of times per second so it is essential that I have
optimised (for speed) atol() and ltoa() functions.

Here is my attempt at ltoa()... (The __fastcall keyword is to tell my
compiler to pass arguments through registers and is used instead of inline
because it seems to be just as fast and this function gets called from
various modules ..).

static char * __fastcall myltoa(long n,char * s)
{
register long r, k;
register int flag = 0;
register int next;

next = 0;
if (n == 0) {
s[next++] = ''0'';
}
else {
if (n < 0) {
s[next++] = ''-'';
n = -n;
}

if(n < 100) goto label2;
if(n < 100000) goto label1;

k = 1000000000;
r = n/k;
if(flag) s[next++] = ''0'' + r;
else if(r > 0){ s[next++] = ''0'' + r;flag = 1;}
n -= r * k;

k = 100000000;
r = n/k;
if(flag) s[next++] = ''0'' + r;
else if(r > 0){ s[next++] = ''0'' + r;flag = 1;}
n -= r * k;

k = 10000000;
r = n/k;
if(flag) s[next++] = ''0'' + r;
else if(r > 0){ s[next++] = ''0'' + r;flag = 1;}
n -= r * k;

k = 1000000;
r = n/k;
if(flag) s[next++] = ''0'' + r;
else if(r > 0){ s[next++] = ''0'' + r;flag = 1;}
n -= r * k;

k = 100000;
r = n/k;
if(flag) s[next++] = ''0'' + r;
else if(r > 0){ s[next++] = ''0'' + r;flag = 1;}
n -= r * k;
label1:
k = 10000;
r = n/k;
if(flag) s[next++] = ''0'' + r;
else if(r > 0){ s[next++] = ''0'' + r;flag = 1;}
n -= r * k;

k = 1000;
r = n/k;
if(flag) s[next++] = ''0'' + r;
else if(r > 0){ s[next++] = ''0'' + r;flag = 1;}
n -= r * k;

k = 100;
r = n/k;
if(flag) s[next++] = ''0'' + r;
else if(r > 0){ s[next++] = ''0'' + r;flag = 1;}
n -= r * k;
label2:
k = 10;
r = n/k;
if(flag) s[next++] = ''0'' + r;
else if(r > 0){ s[next++] = ''0'' + r;flag = 1;}
n -= r * k;

r=n;
s[next++] = ''0'' + r;
}
s[next] = ''\0'';
return(s);
}
The goto''s are there because I recognised that the majority of numbers are
less than 100 (mainly return codes from functions) and those that are not
less than 100 tend to be less than 100,000 (this language is not usually
used for mathemetics). This did give me another 15-20% improvement in
speed on a tight loop going some arithmetic..

By the way, I have tried pre-calculating integer values for all strings
pushed onto the stack (by always appending the 4 byte integer value on the
stack at the end of the string, but it actually caused a slowdown since the
I have to do a atol() on every function return value or string concatenation
operation even if the value is not going to be used in an arithmetic or
comparison operation.

Any hints would be welcome...

Sean

推荐答案

Sean Kenwrick写道:
Sean Kenwrick wrote:

我正在为一种语言编写一个字节码解释器/模拟器使用字符串作为变量(即所有变量都被作为字符串压入堆栈)。因此对于算术运算我需要转换字符串为32位整数,执行算术运算,然后将其转换回字符串,然后将其推回堆栈。
这可能每秒发生数百万次因此对我来说至关重要已经优化(用于速度)atol()和ltoa()函数。

这是我对ltoa()的尝试......(__ fastcall关键字是告诉我的
编译器通过寄存器传递参数,而不是内联使用
因为它似乎同样快,并且从各个模块中调用了这个函数..)。

静态字符* __fastcall myltoa(long n,char * s)
{
注册长r,k;
注册int flag = 0;
注册int next;

next = 0;
if(n == 0){
s [next ++] =''0'';
}
如果(
if) n< 0){
s [next ++] ='' - '';
n = -n;


未定义的行为如果(-LONG_MAX> n)

}

if(n< 100)goto label2;
if(n< 100000)goto label1;

k = 1000000000;
r = n / k;
if(flag)s [next ++] ='' 0''+ r;


if(flag)

flag已经知道为零。

else if(r> 0){s [next ++] =''0''+ r; flag = 1;}


任何提示都是受欢迎的......

I am writing a byte-code interpreter/emulator for a language that
exclusively uses strings for variables (i.e all variables are pushed onto
the stack as strings). Therefore for arithmetic operations I need to
convert the string to a 32 bit integer, carry out the arithmetic operation,
then convert it back to a string before pushing it back onto the stack.
This can happen millions of times per second so it is essential that I have
optimised (for speed) atol() and ltoa() functions.

Here is my attempt at ltoa()... (The __fastcall keyword is to tell my
compiler to pass arguments through registers and is used instead of inline
because it seems to be just as fast and this function gets called from
various modules ..).

static char * __fastcall myltoa(long n,char * s)
{
register long r, k;
register int flag = 0;
register int next;

next = 0;
if (n == 0) {
s[next++] = ''0'';
}
else {
if (n < 0) {
s[next++] = ''-'';
n = -n;
Undefined behavior if (-LONG_MAX > n)
}

if(n < 100) goto label2;
if(n < 100000) goto label1;

k = 1000000000;
r = n/k;
if(flag) s[next++] = ''0'' + r;
if(flag)
flag is already known to be zero, at this point.
else if(r > 0){ s[next++] = ''0'' + r;flag = 1;}
Any hints would be welcome...




请为我计时:


#include< limits.h>

char * lto_a(long n,char * s)

{

char c,* p,* q;

int flag = 0;


q = p = s;

if(0> n){

* p ++ ='' - '';

+ + s;

if(-LONG_MAX> n){

flag = 1;

n = LONG_MAX;

}否则{

n = -n;

}

}

做{

* p ++ =(char)(n%10 +''0'');

n / = 10;

} while(n!= 0);

if(flag){

++ * s;

}

for(* p =''\\ \\ 0''; --p> s; ++ s){

c = * s;

* s = * p;

* p = c;

}

返回q;

}


-

pete



Please time this for me:

#include <limits.h>
char *lto_a(long n, char *s)
{
char c, *p, *q;
int flag = 0;

q = p = s;
if (0 > n) {
*p++ = ''-'';
++s;
if (-LONG_MAX > n) {
flag = 1;
n = LONG_MAX;
} else {
n = -n;
}
}
do {
*p++ = (char)(n % 10 + ''0'');
n /= 10;
} while (n != 0);
if (flag) {
++*s;
}
for (*p = ''\0''; --p > s; ++s) {
c = *s;
*s = *p;
*p = c;
}
return q;
}

--
pete




" ;皮特" < PF ***** @ mindspring.com>在消息中写道

新闻:40 *********** @ mindspring.com ...

"pete" <pf*****@mindspring.com> wrote in message
news:40***********@mindspring.com...
Sean Kenwrick写道:
Sean Kenwrick wrote:

我正在为一种语言编写一个字节码解释器/模拟器,这种语言专门使用字符串作为变量(即所有变量都将
作为字符串推送到堆栈中)。因此,对于算术运算,我需要将字符串转换为32位整数,执行算术
操作,然后将其转换回字符串,然后再将其推回堆栈。
这每秒可能发生数百万次,所以我需要b $ b优化(速度)atol()和ltoa()函数。

这是我对ltoa()的尝试。 。(__ fastcall关键字是告诉我的
编译器通过寄存器传递参数并使用而不是
inline,因为它看起来同样快,并且从各个模块调用此函数。 。)。

静态字符* __fastcall myltoa(long n,char * s)
{
注册长r,k;
寄存器int flag = 0;
注册int next;

next = 0;
if(n == 0){
s [next ++] =''0'';
}
else {
if(n< 0){
s [next ++] ='' - '';
n = -n;
未定义的行为if(-LONG_MAX> n)

I am writing a byte-code interpreter/emulator for a language that
exclusively uses strings for variables (i.e all variables are pushed onto the stack as strings). Therefore for arithmetic operations I need to
convert the string to a 32 bit integer, carry out the arithmetic operation, then convert it back to a string before pushing it back onto the stack.
This can happen millions of times per second so it is essential that I have optimised (for speed) atol() and ltoa() functions.

Here is my attempt at ltoa()... (The __fastcall keyword is to tell my
compiler to pass arguments through registers and is used instead of inline because it seems to be just as fast and this function gets called from
various modules ..).

static char * __fastcall myltoa(long n,char * s)
{
register long r, k;
register int flag = 0;
register int next;

next = 0;
if (n == 0) {
s[next++] = ''0'';
}
else {
if (n < 0) {
s[next++] = ''-'';
n = -n;
Undefined behavior if (-LONG_MAX > n)
}

if(n< 100)goto label2;
if(n< 100000)goto label1;

k = 1000000000;
r = n / k;
if(flag)s [next ++] =''0''+ r;
}

if(n < 100) goto label2;
if(n < 100000) goto label1;

k = 1000000000;
r = n/k;
if(flag) s[next++] = ''0'' + r;



if(flag)
此时已知标志为零。



if(flag)
flag is already known to be zero, at this point.

else if(r> 0){s [next ++] ='' 0''+ r; flag = 1;}
else if(r > 0){ s[next++] = ''0'' + r;flag = 1;}





欢迎任何提示...


请为我计时:

#include< limits.h>
char * lto_a(long n,char * s)
{
char c, * p,* q;
int flag = 0;

q = p = s;
if(0> n)



Please time this for me:

#include <limits.h>
char *lto_a(long n, char *s)
{
char c, *p, *q;
int flag = 0;

q = p = s;
if (0 > n)



* p ++ ='' - '';
++ s;
if(-LONG_MAX> n){
flag = 1;
n = LONG_MAX;
} else {
n = -n;
}
}
做{
* p ++ =(char)(n%10 +''0'');
n / = 10;
} while(n!= 0);
if(flag){
++ * s;
}
for(* p =''\\ \\0 ''; --p> S; ++ s){
c = * s;
* s = * p;
* p = c;
}
返回q;
}

-
pete


*p++ = ''-'';
++s;
if (-LONG_MAX > n) {
flag = 1;
n = LONG_MAX;
} else {
n = -n;
}
}
do {
*p++ = (char)(n % 10 + ''0'');
n /= 10;
} while (n != 0);
if (flag) {
++*s;
}
for (*p = ''\0''; --p > s; ++s) {
c = *s;
*s = *p;
*p = c;
}
return q;
}

--
pete




我将调用更改为__fastcall并使用寄存器变量后它非常
略慢(我的花了4650ms,你花了4860ms花了1,000,000次

循环做了一些简单的算术)。差异可能在最后需要的

strrev() - 但我喜欢从右到左的

的解决方案,我想我有一个版本,最后可能不需要strrev()

.....我会发布我的尝试和稍后的时间......


谢谢

Sean



After I change the call to __fastcall and use register variables It''s very
slightly slower (mine took 4650ms, yours took 4860ms for a 1,000,000 times
loop doing some simple arithmetic). The difference is probably in the
strrev() required at the end - but I like the solution of going from the
right to left and I think I have a version that might not need the strrev()
at the end..... I will post my attempt and the timing later...

Thanks
Sean


这个怎么样?


#include< limits.h>


#if INT_MAX == 0x7FFFFFFF&& INT_MIN + 2147483647> = - 1

/ *假定32位带符号算术* /

char * myltoa(长n,字符* s)

{

unsigned short j = 1;

if(n< 0)

{/ *处理负数* /

s [0] ='' - ''; ++ j;

if(INT_MIN + 2147483647 == - 1&& n == INT_MIN)

{/ * handle -2147483648艰难之路* /

s [1] ='''2''; ++ j;

n = -147483648;

}

n = -n;

}

/ *使用有点二分法找到长度* /

s [j + =(n <10000)?(n< 100)?(n> = 10):( n> = 1000) +2:

(n< 100000000)?(n< 1000000)?(n> = 100000)+4:

(n> = 10000000)+6 :( n> = 1000000000)+8] =''\''';

/ *从右向左转换* /

do s [ - j] = N%10 +'0'; while((n / = 10)!= 0);

/ *全部完成* /

return(s);

}

#endif

Fran?ois Grieu
What about this?

#include <limits.h>

#if INT_MAX==0x7FFFFFFF && INT_MIN+2147483647>=-1
/* 32 bit signed arithmetic assumed */
char *myltoa(long n, char *s)
{
unsigned short j = 1;
if (n<0)
{ /* handle negatives */
s[0] = ''-''; ++j;
if (INT_MIN+2147483647==-1 && n==INT_MIN)
{ /* handle -2147483648 the hard way */
s[1] = ''2''; ++j;
n = -147483648;
}
n = -n;
}
/* find length using kinda dichotomy */
s[j += (n<10000)?(n<100)?(n>=10):(n>=1000)+2:
(n<100000000)?(n<1000000)?(n>=100000)+4:
(n>=10000000)+6:(n>=1000000000)+8] = ''\0'';
/* convert from right to left */
do s[--j] = n%10+''0''; while ((n/=10)!=0);
/* all done */
return(s);
}
#endif
Fran?ois Grieu


这篇关于任何人都可以进一步提高......的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆