5ちゃんねる ★スマホ版★ ■掲示板に戻る■ 全部 1- 最新50  

■ このスレッドは過去ログ倉庫に格納されています

トリッキーなコード その2

1 :デフォルトの名無しさん:02/11/25 18:12
独りよがりのためのスレッド
大体トリッキーなコードを書く奴に限って
致命的なバグを出したりするんだけど、
書きたいもんはしょうがない。

・・・らしい


前スレ http://pc3.2ch.net/test/read.cgi/tech/983191866

2 :デフォルトの名無しさん:02/11/25 18:16
自由と正義の名の下に2ゲット!

       ./"´:;;::;;;: ::::;::"ソヽ
       / ,ヘ〜-ー'´⌒``ヽ:ヽ
      / ノ 彡:三:三:三:ミ |: \
      | |. __,,;;ィ  t;;;;,,,_ :ヽ│
       | |シ ,ィェァ') (.yェュ、 ミ| |
      !r、|  ''''''. | | ''''''  Y )
      ヽ{ ヽ. (r、 ,n)  /:: };ノ
       し}  : 、___二__., ;:::::jJ   
        !、.:. ´ ..::::... `ノ::::ノ  
        _,〉、ゝ '""'ノ/:|      
      __,,ィ';;;;ト `ニニ: ::..ノ|ヽ、 _ 
 -ー''''"";;;;;;;;;;;;ヽ \::::::::/ /;;;;;;;;;;;`''ー-、,,,,__
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ヽ   ><  /;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"''
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ヽ /|;;;jヽ、/;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
自由と正義の名の下に、このスレにアメリカが介入しました。
以下、大統領に従ってください。

>>1弱いくせに調子に乗るなよこのジャップ豚(プ
>>2
>>3スモウレスラーかと思ったら、ただのデブか(プ
>>4コリアもジャップも同類だろエテ公(プ
>>5米ばっか食ってんな(プ
>>6トマホークかますぞ(プ
>>7エロアニメが文化かよ(プ
>>8ロリコン必死だな(プ
>>9イラクの次はお前だな(プ


3 :デフォルトの名無しさん:02/11/25 18:16
うにしす

4 :デフォルトの名無しさん:02/11/25 18:20
↓タリバソ

5 :デフォルトの名無しさん:02/11/25 18:50
↑アソパソマソ

6 :デフォルトの名無しさん:02/11/25 19:20
↓エロカイダ

7 :デフォルトの名無しさん:02/11/25 19:54
↑ザビエロ

8 :デフォルトの名無しさん:02/11/25 21:44
True = Not False
まさにトリッキー

9 :デフォルトの名無しさん:02/11/27 01:38
>8
True = Not False
証明して下さい

10 :デフォルトの名無しさん:02/12/08 02:45


11 :デフォルトの名無しさん:02/12/08 02:45


12 :デフォルトの名無しさん:02/12/08 02:45


13 :デフォルトの名無しさん:02/12/09 00:31
_;main(){(9^_^9);} /* こんなの見た */

14 :デフォルトの名無しさん:02/12/10 13:38
// 知られざるC言語の演算子

// 標準仕様には入っていない(と思う)のですが、
// 初期ccでサポートされていたこともあり、
// たいていのコンパイラで実装されている知られざる演算子をご存じですか?

int main(void)
{
  int a=10,b=7;
  printf("割ってかける演算子、かけて割る演算子\n");

  // 3で割ってから3でかける演算子
  a/*=3;
  
  // 5でかけてから5で割る演算子
  b*/=5;

  printf("a=%d b=%d\n",a,b);
  return 0;
}

15 :デフォルトの名無しさん:02/12/10 18:26
#include <stdio.h>
int main (void)
{
printf ("( ´_ゝ`)フーン\n");
return 0;
}

16 :デフォルトの名無しさん:02/12/10 20:57
前スレのお題を変えてみて……

◆ある図形内に点が含まれるかどうかを高速に判断する

という問題はどう?
図形は、n個の点(x_1,y_1)-(x_n,y_n)で与えられるとしましょう。
n>=3で、(x_n,y_n)と(x_1,y_1)は繋がっていると考えてください。
このn個の点は、隣同士を線で結んでも、線が交わることがないものとします。

高速化のために条件を付加してもOKですが、明記してください
(例えば、凹んでいる部分は絶対に無い、n==4である、とか)

難しそう

17 :デフォルトの名無しさん:02/12/10 21:03
短形(x1,y1)-(x2,y2)なら、最速は
(x>=x1 && x<=x2 && y>=y1 && y<=y2)
でいいのかな?

18 :デフォルトの名無しさん:02/12/10 22:39
>>14
a=5 b=7 となるだけだが ?
(なんで、b*/=10; にしないんだろう...。)

19 :デフォルトの名無しさん:02/12/10 23:59
>>18
コンパイラバグってるよ。アセンブラ出力して確認汁。

20 :デフォルトの名無しさん:02/12/11 00:24
>>18
それって古典的なネタじゃん
main() {
printf("%03d\n", 001);
printf("%03d\n", 010);
printf("%03d\n", 100);
}
これといい勝負。


21 :デフォルトの名無しさん:02/12/11 01:04
>>19
いくつになるのが正解なの ?

22 :デフォルトの名無しさん:02/12/11 01:15
>>21
自分でソース打ち込んで試せ。
ちゃんと自分でエディタを使って打てよ。
あとメモ帳やviみたいな色分けもできんような
エディタはミスしやすいから使うなよ。

23 :デフォルトの名無しさん:02/12/11 01:30
>>22
viは最近は色分けできるよ

24 :22:02/12/11 01:42
>>23
それは vim ではなかと?

25 :デフォルトの名無しさん:02/12/11 01:49
>>24
ごめん、そうだね。

26 :デフォルトの名無しさん:02/12/11 02:31
>>21
Cなら
// 3で割ってから3でかける演算子
でエラーが出るのが妥当 (でも無いかも知れない)
C++なら
a=5, b=7 ;
>>18で正しい


27 :デフォルトの名無しさん:02/12/11 17:12
>>26
今の時代、Cコンパイラにだって
C++のコメントを許容するオプションくらいあるでしょ

28 :デフォルトの名無しさん:02/12/11 19:11
10/3*3
なんだから
a=9
じゃないの??

29 :デフォルトの名無しさん:02/12/11 19:43
>>28
正しいC環境がインストールされていませんね。

30 :デフォルトの名無しさん:02/12/11 23:58
>>28
だから自前で書いて試せって。
色付け可能なエディタでな。

31 :デフォルトの名無しさん:02/12/12 00:07
>>28
/* だからネタなんだって */

32 :デフォルトの名無しさん:02/12/12 00:27
a/*=3;
b*/=5;

a
/*=3; b*/
=5;
だから
a=5;

33 :デフォルトの名無しさん:02/12/12 03:09
>>32
(゚Д゚)ハァ?

34 :デフォルトの名無しさん:02/12/12 03:15
>>33
(゚Д゚)ハァ?

35 :デフォルトの名無しさん:02/12/12 09:37
まぁ初めて見たやつには面白いネタだったろうな。

初めて見ました。

36 :デフォルトの名無しさん:02/12/12 22:16
>>35
一人ボケ一人突っ込みかよ。

37 :デフォルトの名無しさん:02/12/12 23:25
よく似たネタに、ポインタが指す値で割るというのがあるね。
 a = 1/*p;

38 :デフォルトの名無しさん:02/12/13 05:26
>>36
むしろ一人突っ込み一人ボケ。


39 :デフォルトの名無しさん:02/12/13 11:34
>>37
普段から
a = 1 / *p;
のように演算子の前後に空白を開けてれば問題ない。

40 :デフォルトの名無しさん:02/12/13 16:55
正直、面白かった。

41 :デフォルトの名無しさん:02/12/13 17:29
まだよく解かってないヤシがいるみたいだな

俺の事です

42 :デフォルトの名無しさん:02/12/14 23:49
まさにトリッキー
楽しかった。

43 :デフォルトの名無しさん:02/12/19 01:11
age
トリッキーの1ってここのスレの人?

44 :デフォルトの名無しさん:02/12/19 01:40
前スレのコレすげー・・・

xor eax, ebx
xor ebx, eax
xor eax, ebx

いただきました。

45 :デフォルトの名無しさん:02/12/19 01:47
ax固定の命令を使わなければ
入れ替える必要は、ほとんど無いだろ

46 :デフォルトの名無しさん:02/12/19 02:14
前スレ読んだら解った。トリッキーの1は前スレの1だね。
すげー盛り上がっててかなりいい感じだったね<前スレの最初の方。
このスレにも降臨してくれないかな・・

47 :デフォルトの名無しさん:02/12/19 02:46
宿題キボンヌ

48 :デフォルトの名無しさん:02/12/19 02:51
漏れはむしろ↓に衝撃を受けた。
int main=0xc3;

49 :デフォルトの名無しさん:02/12/19 03:00
0xc3ってx86系のリターンだっけ…?

50 :デフォルトの名無しさん:02/12/19 04:16
>>44
最近のCPUではパイプラインが有効に働かず遅くなるだけ。

51 :デフォルトの名無しさん:02/12/19 04:48
>>50
その言い方、ダウトっぽい

52 :デフォルトの名無しさん:02/12/19 09:22
100 nop
101 jmp 100

53 :デフォルトの名無しさん:02/12/19 09:23
repeat
loop

54 :デフォルトの名無しさん:02/12/19 09:29
;トリッキー


55 :デフォルトの名無しさん:02/12/19 18:50
#!/usr/bin/perl
$x=$_='#!/usr/bin/perl&$x=$_=";&s/\046/\n/g;s/\042/\047$x\047/;print;&';
s/\046/\n/g;s/\042/\047$x\047/;print;


56 :デフォルトの名無しさん:02/12/20 00:06
なんで、誰も >>17 の短形に突っ込んでないの?
おまいら皆アフォ?
矩形(くけい)だろ、ヴォケ

57 :デフォルトの名無しさん:02/12/20 00:19
>>56
2ch でその突っ込み...、しかも10日も立ってから...。
はっ !! もしかして本人なのか ?

58 :56:02/12/20 00:24
いや、今日初めてこのスレ読んだ
今前スレ読んでるんだが面白いな

短形ってがいしゅつとかの類かね、素で間違ってそうなんだが

59 :56:02/12/20 01:20
スマソ、前スレのラストのほうでちゃんと矩形って書いてたな


60 :デフォルトの名無しさん:02/12/20 02:11
>>56
いきなりキレかよ!

61 :デフォルトの名無しさん:02/12/20 02:20
>>60
思わず短小、もとい苦笑

62 :56:02/12/20 02:54
スマソ、知り合いに「たんけい、たんけい」と連発するヤツが居てな
いつも突っ込めずに居るんだ(;´д`)ストレスタマルヨー


63 :デフォルトの名無しさん:02/12/20 02:58
前スレみたいなノリキボンヌ

64 :56:02/12/20 04:48
スレ汚した詫びにネタ振り

任意の文字列を、10進数に変換するコードを書きなさい。
char *binary = "11011100";
int decimal;
/* */
printf("%s is %d\n",binary,decimal);


65 :デフォルトの名無しさん:02/12/20 04:58
> 任意の文字列を、10進数に変換するコードを書きなさい。

この文がどれだけ曖昧で意味不明か、自分でわかってる?
数値自体は2進数で「表示」しようと10進数で「表示」しようと
同じ値だから変換もなにもないし、
そもそも元の文字列が何進数を文字列にしたものなのかわからない。

多分、「任意の2進数を表す文字列を数値に直し、10進数として表示しなさい」
って意味だと思うけど。

66 :デフォルトの名無しさん:02/12/20 10:16
>65
uzeeeeeeeeeeeee
いつも客にうだうだ言ってそう

67 :デフォルトの名無しさん:02/12/20 12:07
見りゃ分かるだろ、何か嫌な事でもあったか?



68 :デフォルトの名無しさん:02/12/20 12:36
>>67
> 見りゃ分かるだろ、
仕様書もまともに書けない客にこう言われてカリカリしてたんじゃないですか。

69 :デフォルトの名無しさん:02/12/20 13:41
>>55
だれも反応してくれないけど,地雷だと思った?
実行すると,自分自身を表示するperlプログラムでした.
Cで同じことするプログラム キボンヌ

70 :デフォルトの名無しさん:02/12/20 13:45
取りあえず職場でXPもどきを導入しはじめてるんだが

仕様書まともに書けない客=普通
客から仕様を上手く引き出せない技術屋=無能

だと思った。

71 :デフォルトの名無しさん:02/12/20 14:14
>>69
> 実行すると,自分自身を表示するperlプログラムでした.
それは分かるけど、

> Cで同じことするプログラム キボンヌ
そういう意図が隠されていたとは気づかなかった。

72 :デフォルトの名無しさん:02/12/20 14:15
仕様の問題は激しくスレ違いだと思います。
ワインバーグの「要求仕様の探検学」でも読みましょう、ということで
http://www.amazon.co.jp/exec/obidos/ASIN/4320023528/ref=sr_aps_b_/249-2652411-1648337

>>69
前スレ見てね。不動点プログラムで検索すれば見つかるよ。
トリッキーの1によれば、
10 LIST
だそうです(笑)

>>64
まずは素直なコードから。コンパイルしてないのでエラーあったらスマソ
char* p=binary;
while(*(p++));
for(int r=0,i=0;p!=binary;--p,++i) r+=(1<<i)*(*p-'0');

73 :デフォルトの名無しさん:02/12/20 14:15
>>70
> 客から仕様を上手く引き出せない技術屋=無能
技術屋つってもいろいろあるわけだが、「客から仕様を引き出す」ってのがSE
の仕事だから、それがうまくできないSEなら無能だな。


74 :デフォルトの名無しさん:02/12/20 14:22
>>72
自己レスすまそ。バグ内包してますな。
でもまぁトリッキーでないコードなので修正はやめておきます

75 :デフォルトの名無しさん:02/12/20 18:43
>>70
うちはいつまでたっても ひとりXP ですよ

76 :デフォルトの名無しさん:02/12/20 19:21
>>62
「もしかしてクケイの事?(笑)」ぐらいにして

77 :デフォルトの名無しさん:02/12/20 19:22
最近思うんだが、数年前に比べて格段に質の低いレスを見ると、
このスレに限らずこの板の全体的な(技術or人間)レベルが落ちている
可能性が高いな

78 :デフォルトの名無しさん:02/12/20 21:11
まぁ俺がいるぐらいだからな

79 :デフォルトの名無しさん:02/12/20 21:25
>>64
どうでしょ?
char *p = binary;
decinal = 0;
while (*p) decimal = (decimal << 1) | (*p++ - '0');

80 :79:02/12/20 21:32
s/decinal/decimal/;

81 :8:02/12/20 23:12
>>9
小売だからそれ以上証明できない

82 :デフォルトの名無しさん:02/12/21 01:17
>>79
お前さぁ、それに"10"を渡したらなんて表示されるか考えてみたか?

83 :デフォルトの名無しさん:02/12/21 01:33
2進数文字列解析
多分最速ではないかと

unsigned int d=0,i=sizeof(int)*8;
char *p=binary;

while(*p!='\0') (*(p++)-'0')?d+=(1<<(--i)):i--;
d>>=i;

84 :デフォルトの名無しさん:02/12/21 01:34
あ、最速ではないな…
文字列→変数のマップを用意して(以下略)

85 :デフォルトの名無しさん:02/12/21 01:38
>>56
char *p="任意の文字列";
long num = (int)p;

「任意の文字列を10進数に変換しろ」だけではこーいう解釈も(無理矢理)成り立つ罠。
元の文字列の条件と、読み取りルールをきちんと書け。
ex.
「'0'と'1'からなる任意の文字列を2進数として読み取り、
 結果を数値型変数に格納せよ」

86 :デフォルトの名無しさん:02/12/21 01:40
>>85
いや、もうその話題は終わったから

つーか何でそんなに粘着なの?

87 :デフォルトの名無しさん:02/12/21 02:09
>>82
何処からどう見ても2

88 :デフォルトの名無しさん:02/12/21 02:17
もろもろの判定を含め、さらにトリッキーに
#include <limits.h>
char *p=binary;
unsigned int c,d=0,i=sizeof(int)*CHAR_BIT+1;
while(((c=*p++-'0')>>1)==0&&--i)d=(d<<1)+c;

89 :デフォルトの名無しさん:02/12/21 02:30
toiuka、>>79ではなにが悪いの?

90 :デフォルトの名無しさん:02/12/21 02:34
矩形の問題はどうなったのか気になったり気にならなかったり

91 :デフォルトの名無しさん:02/12/21 02:58
更にトリッキーに (評価順はpの再利用を考え)
while(--i&&((c=*p++-'0')>>1)==0)d+=d+c;

92 :デフォルトの名無しさん:02/12/21 03:05
どの辺がトリッキーなのかと小一時間(ry
七行かぶれで短くしてるだけやん

93 :デフォルトの名無しさん:02/12/21 11:13
アセンブラでトリッキーなのいってみよ

94 :デフォルトの名無しさん:02/12/21 11:29
Windows上で動くAssembler Virusとか。

95 :デフォルトの名無しさん:02/12/21 23:24
某CADソフトのAPIの仕様はカナーリトリッキーです。

なにせ「ファイルを自動で開く」という至極基本的な動作を行う
プラグインが簡単に作れない。

96 :デフォルトの名無しさん:02/12/21 23:38
>>95
よー知らんけど、それはお前の技術力がないからということはないのか ?

97 :デフォルトの名無しさん:02/12/22 22:26
>>95
漏れに技術力があるかどうかは知らんが、
そのソフトのAPIだけでは実現できず(どーやっても選択ダイアログが出る)、
キーストロークのエミュレートしたり、DDEコマンド投げたりせんと実現できん
というのはどう考えても変だと思うんだよ…

ちなみにマニュアルには「スクリプトを実行しる!」みたいな事が書いてあった。
しかも上記の手を使ってもプラグイン実行中に開けない。
(本体がコマンド受付状態になってからでないと開かない)

98 :デフォルトの名無しさん:02/12/22 23:59
それはトリッキーなんじゃなくて、クソなだけじゃないか?


99 :デフォルトの名無しさん:02/12/23 00:25
>>98
禿同、回避方法がトリッキーだったりするけど。

100 :デフォルトの名無しさん:02/12/23 00:56
そのトリッキーはなんかスレ違いの香り
100get

101 :95:02/12/24 00:54
スレチガイスマンカッタ。
オブジェクトGetした後の開放手段がバラバラ
(free、delete、独自関数、開放不要のごちゃ混ぜ)
とかいった話はマ板でネタにしてきます。
これで業界トップのシェア持ってるというから、驚きなんだよなぁ…

102 :デフォルトの名無しさん:02/12/24 06:28
互換性とかの理由からだんだんぐちゃぐちゃになったんじゃなくて
最初からそうなの?
Windowsにもメモリ管理のAPIが何種類あることか…

103 :デフォルトの名無しさん:02/12/24 15:07
44 は xchg eax, ebx ではあかんか?

104 :デフォルトの名無しさん:02/12/24 15:47
>>103
いいと思うけど、例えば 下位6bitだけ交換したいような場合に応用出来るのは >.44

105 :デフォルトの名無しさん:02/12/24 15:51
> 下位6bitだけ交換

44 でそんなことができるの?

106 :デフォルトの名無しさん:02/12/24 15:54
前スレにこう書いてあったけど、どの程度なんだ?

> xchg 命令は遅いのだよ

107 :デフォルトの名無しさん:02/12/24 16:29
>>105 AND 直値を入れたら出来た気がするけど…

108 :デフォルトの名無しさん:02/12/24 16:35
あ、ゴメン、もうひとつレジスタ使わないと交換出来ないや

109 :デフォルトの名無しさん:02/12/24 17:24
>>106
マルチプロセッサ環境ではlockが入るので、
タイトなループでやらかすと酷いことになる。

シングルプロセッサで遅いという話は知らない。

110 :デフォルトの名無しさん:02/12/24 18:44
>>109
レジスタ同士でも?

111 :デフォルトの名無しさん:02/12/24 20:00
>>105
実際のコード書いてみて。

112 :111:02/12/24 20:00
間違い。

>>107
実際のコード書いてみて。

113 :107:02/12/24 20:49
>>112 格好悪いけどこうかな
  mov ebx,eax
  xor ebx,edx
  and ebx,63
  xor edx,ebx
  xor eax,ebx

>>110 たぶん 勘違いしてると思う P2かP3かで XCHG は >>44 の3命令と同じ負荷の筈

114 :デフォルトの名無しさん:02/12/24 21:50
>>113
なるほどー。
さんくす。

115 :デフォルトの名無しさん:02/12/24 22:07
IA-32マニュアルによると、XCHGはオペランドに関わらず常にLOCKを吐く。

>>113 は嘘を仕込むなよ。

116 :!113:02/12/25 01:28
>>115
マニュアルには
XCHG命令には自動的にLOCKプリフィックスが付くものと想定されている
と書かれているが、前後の文意から
LOCKが必要なものは、自分でLOCKしてね♪
と言う意味で、常にLOCK#信号を出す訳では無いに100カノッサ

117 :デフォルトの名無しさん:02/12/25 03:17
> xor 3回よりも速い罠
> mov 3回よりも速いみたいだが
> push/popは勿論論外(w
なの?xchgはパイプライン崩すとかあった気がしたが。
クロック計算は486時代以来してないので最近のは知らんのだが。

118 :デフォルトの名無しさん:02/12/25 06:02
パイプライン出てきてからクロック計算する気がしなくなった漏れは、もうだめぽ?

119 :107:02/12/25 08:47
ああ、なるほど。 
>XCHG 命令は、LOCK プリフィックスの有無に関係なく、常にLOCK# 信号をアサートする。
これを読んで勘違いしたんだな。でも、

>メモリ・オペランドが参照されていると、
>LOCK プリフィックスの有無、あるいはIOPL の値に関係なく、プロセッサのロッキング・プ
>ロトコルが交換操作が持続している間自動的にインプリメントされる。

だから、これは対メモリに関する項だと思うよ。
それに、
>NOP 命令は、XCHG (E)AX, (E)AX 命令の別名ニーモニックである。
だから もし必ず XCHG が LOCK#アサートだとすると NOPでも同じ事になる。

確認したら  XCHG eAX,r16/32 uOP数は3みたい

120 :デフォルトの名無しさん:02/12/25 10:57
> xchgはパイプライン崩すとかあった気がしたが。

P5ではペアリング不可。
P6以降はu-opに分解される?
でもリネーミングならOP数1のような。

121 :デフォルトの名無しさん:02/12/26 02:31
スレたてるまでもない質問スレから誘導できました。
スコープ解決演算子の無い(ANSI準拠)Cで
グローバル変数を使うときに
struct{
int a; //・・・



FILE in; //・・・
}global;
と定義して、使うときにわざわざglobal.aとかやってるんですけど
同じ方法とってる人や、もっといい方法を知ってる方いませんかー?

122 :デフォルトの名無しさん:02/12/26 03:33
>>121 まぁ質問ならあげろぃ

123 :デフォルトの名無しさん:02/12/26 03:35
void main()
{
 char *p = strcpy((char*)malloc(strlen("hello,world\h")+1), "hello,world\n");
 printf(*p)
}

124 :デフォルトの名無しさん:02/12/26 03:42
>>121
似たようなことを偶にやります。
オレの場合、globalでなく、そのソースのファイル名にちなんだ名前を付けます。

static付けるとマップファイルに出てこなくなるから、
ユニークな名前を付けるために、ファイル名を頭に付けるようにした。
関連するグローバル変数を構造体にまとめるようにし始めた。
そうこうしているうちに全部構造体に押し込むようになってしまいました。

125 :デフォルトの名無しさん:02/12/26 03:43
*つけちゃいかんだろ

126 :デフォルトの名無しさん:02/12/26 04:07
(^*^)

127 :デフォルトの名無しさん:02/12/26 07:50
顔?
後ろから見たケツ?


128 :デフォルトの名無しさん:02/12/26 11:30
>>121
それで何か困るの?

まぁ、あとは命名規則などをしっかりとすれば、
グローバル変数との衝突なんてそう簡単には起こらないと思うけれど、
規模によってはあり得るだろうな。

129 :デフォルトの名無しさん:02/12/26 14:31
>>106
いまさらだが試してみたガッテン。

改行が多いと怒られたので以下、分割。

#include <windows.h>
#include <stdio.h>

#defineLOOP500000
#define_ALIGN_//align 2

func1()
{
_asm
{
movecx, LOOP
_ALIGN_
f1:movedx, eax
moveax, ebx
movebx, edx
dececx
jnzf1
}
}


130 :129:02/12/26 14:32
func2()
{
_asm
{
movecx, LOOP
_ALIGN_
f2:xoreax, ebx
xorebx, eax
xoreax, ebx
dececx
jnzf2
}
}
func3()
{
_asm
{
movecx, LOOP
_ALIGN_
f3:xchgeax, ebx
dececx
jnzf3
}
}


131 :129:02/12/26 14:33
func4()
{
_asm
{
movecx, LOOP
_ALIGN_
f4:pusheax
pushebx
popeax
popebx
dececx
jnzf4
}
}

int prof(void (func)())
{
__int64start, end, freq;
HANDLEhprocess;
DWORDoldclass;

hprocess = GetCurrentProcess();
oldclass = GetPriorityClass(hprocess);



132 :129:02/12/26 14:33

Sleep(10);
SetPriorityClass(hprocess, REALTIME_PRIORITY_CLASS);
QueryPerformanceFrequency((LARGE_INTEGER*)&freq);
QueryPerformanceCounter((LARGE_INTEGER*)&start);

func();

QueryPerformanceCounter((LARGE_INTEGER*)&end);
SetPriorityClass(hprocess, oldclass);

return (int)(end-start);
}

main()
{
printf("func1 = %d\n", prof(func1));
printf("func2 = %d\n", prof(func2));
printf("func3 = %d\n", prof(func3));
printf("func4 = %d\n", prof(func4));
}

結果
func1 = 6685
func2 = 9706
func3 = 6426
func4 = 10277

xchg が一番早い。xorが一番遅い。


133 :デフォルトの名無しさん:02/12/26 14:36
それ*だけ*を繰り返しても意味ないんでは・・・

134 :デフォルトの名無しさん:02/12/26 14:39
>>129
実行環境は?

135 :デフォルトの名無しさん:02/12/26 14:46
>>133 そうなんだけどね。一応データとして。
>>134 Pen3 のノートPCでつ。ほかの石だとどうなんでしょう?

136 :デフォルトの名無しさん:02/12/26 14:46
>>135
しかも一番遅いのはpush/popだった。鬱


137 :デフォルトの名無しさん:02/12/26 16:46
>>135
OSやCPUの周波数も書いてくれ。

138 :デフォルトの名無しさん:02/12/26 17:50
>>137
比率の問題だろ。周波数は関係ないだろ。
それよりもCPUの世代だろ。
OSもあまり関係ないと思うがな。


139 :デフォルトの名無しさん:02/12/26 17:51
>>138
知ったか君は黙っといたほうがいい。

140 :デフォルトの名無しさん:02/12/26 18:29
漏れも周波数は関係ないと思うが、OS は存分に関係ある気がする。

141 :138:02/12/26 21:34
>>140
そうか?
REALTIME_PRIORITY_CLASSで実行してるんだよな?
タイムスライスをまたがるほど長時間のスレッドが動いてる
ようにも見えないんだけど。

142 :138:02/12/26 21:35
>>141
ひょっとして、LinuxとかFreeBSDとか気にしてるのか?
どうみてもWin32のコードだと思うんだけど。

143 :138:02/12/26 21:36
>>142>>141 は蛇足だった。逝ってくる。

144 :デフォルトの名無しさん:02/12/26 22:36
追試のためには、
環境は関係なさそうでも書いとくのが普通では?

そんな基本も知らないアホがこの板の多数なのか?

145 :デフォルトの名無しさん:02/12/26 22:45
知らん

146 :デフォルトの名無しさん:02/12/26 22:46
わざと追試できないようにして、かく乱するのもテクの一つですよ。
まあ、この場合はベンチマークプログラムそのものが無意味っぽいですが。

147 :デフォルトの名無しさん:02/12/27 01:28
リアルモードとプロテクトモードで結果変わる? 変わらない?

148 :デフォルトの名無しさん:02/12/27 06:01
P6系の場合マニュアル上ではxchgは3μopで1命令ですむのだから
1クロックで1μopの命令が、あと2つ同時に実行出来るはず
( 1クロックで4μopが1つと1μopが2つ同時に実行できる )
他の命令では少なくとも3命令になってしまうので
OSに関係なくP6系ではxchgが1番早い

149 :デフォルトの名無しさん:02/12/27 06:53
各環境での結果まだ?

150 :デフォルトの名無しさん:02/12/27 09:46
138 のようにごねないで、素直に環境書けばいいのに。
環境書きたくない理由があるのか?

151 :107:02/12/27 10:15
procedure TForm1.Button1Click(Sender: TObject);
procedure SwapXCHG(var a,b:Integer) ;
asm
xchg eax, edx
end;
procedure SwapXOR(var a,b:Integer);
asm
xor eax, edx
xor edx, eax
xor eax, edx
end;
function RDTSC:Integer;
asm
RDTSC
end;
var cXCHG,cXOR,c0,c1,i,j:Integer;
var a,b:Integer;
begin
a:=1; b:=2; cXCHG:=0;cXOR:=0;
c0:=RDTSC;
for j:=0 to 9 do begin
for i:=0 to 9 do SwapXCHG(a,b);
c1:=RDTSC;inc(cXCHG,c1-c0);c0:=c1;
for i:=0 to 9 do SwapXOR(a,b);
c1:=RDTSC;inc(cXOR,c1-c0);c0:=c1;
end;
Memo1.Lines.Add(Format('XOR=%5d XCHG=%5d',[cXOR,cXCHG]));
end;
Athron 800M での結果 XOR= 1424 XCHG= 1481
順番を逆転したら逆の結果が出たから、ほぼ同じなんでしょ


152 :デフォルトの名無しさん:02/12/27 10:33
最初のやつがOSなどの環境を書かないと、
残りもマネをするんだなあ。

153 :デフォルトの名無しさん:02/12/27 10:38
>>152
151を良く見ろ、コードが全く違うぞ。
それ以前の問題だ。

154 :107:02/12/27 10:50
あ、ほんとだ。 var は不要だし、そもそも交換した結果を返してないや。
まあ、時間測るだけだからいいか

155 :デフォルトの名無しさん:02/12/27 11:59
>>107 お前はいったい何の時間を計測してんだ?
for や func call やタスクスイッチのオーバーヘッドの方が
大きかったりしないか?
>>129 の方がまだ信憑性ありそうだな。

お前ら >>129 のコード実行してOS、CPU(ステップ&周波数含む)と共に報告スレ。
漏れはスペースが全部なくなってて挫折しますた。(w

156 :デフォルトの名無しさん:02/12/27 12:45
OS云々はともかく、Pentiumに関して言うならば…。

push/pop での交換は確実に遅い。スタック操作を伴なうから
プロテクトモードでならメモリ保護チェックが必ず発生してしまう。
#コンパイラの最適化レベルを上げるとcall/retを減らすように
#アセンブルコードを出力しようとするのもこの理由による。

xor他による交換の場合は、二つ目、三つ目の演算命令は
その前の演算命令によってレジスタ内容が完全確定していないと
演算自体することが出来ないわけだから、それぞれの命令間で
パイプラインストールが発生する可能性が非常に高い。
#それぞれの命令間にNOPを挟んでも実行時間に大差なければほぼ間違いない

xchg の場合、厳密にはレジスタの内容を交換しているのではなくて、
現在ではレジスタの名前のほうを(CPU内部的に)交換していると思っていい。
なので交換対象レジスタの組み合わせによってはストールしにくい(またはしない)
#むかしのCPUでは確かにレジスタ内容自体を交換していた。(RISC系は現在でもそう)
#けど多段パイプラインやコード予測機能の絡みもあるので、
#CISC系ではそういうのに影響を与えにくい設計に進化してきている(はず)

まあ、純粋培養のソフト屋さんにハード依存の話をしても、
なかなか想像力が付いて来ないだろうとは思うけどね…。

157 :デフォルトの名無しさん:02/12/27 12:59
>>156
マジレスカコワルイ

push/popはメモリアクセスする時点で遅いのは確定。
俺の興味はどっちかというとどれ位遅いかだな。

xorやmovによる交換も実質レジスタリネーミングされると
考えればパイプラインストールはほぼ発生してないはず。

129の結果どおりだとすれば、156のとは正反対の
mov/xor 3回よりは xchg の方が早いが、
xchg単体は mov/xor単体よりもずっと遅い
という結果が出てくる。

158 :デフォルトの名無しさん:02/12/27 13:17
そもそもCPUの話題でOS他の環境のネタが出てくるところが痛いね。
ここの住民はそのうちメモリ容量とかHDD容量とかビデオチップとか
言い出す予感。

159 :デフォルトの名無しさん:02/12/27 14:18
前スレ良かったな〜

160 :107:02/12/27 14:48
>>155
負荷を測るなら for や call の時間込みで測定するのがホントじゃないの?
 まあ、ループした方がいいっていうなら
procedure TForm1.Button1Click(Sender: TObject);
procedure SwapXCHG;
var i:Integer;
begin for i:=0 to 100-1 do asm  xchg eax, edx end;
end;
procedure SwapXOR;
var i:Integer;
begin for i:=0 to 100-1 do asm
xor eax, edx
xor edx, eax
xor eax, edx
end;
end;
function RDTSC:Integer;
asm RDTSC
end;
var cXCHG,cXOR,c0,c1,i,j:Integer;
var a,b:Integer;
begin
a:=1; b:=2; cXCHG:=0;cXOR:=0;
c0:=RDTSC;
for j:=0 to 9 do begin
SwapXCHG;  c1:=RDTSC;inc(cXCHG,c1-c0);c0:=c1;
SwapXOR; c1:=RDTSC;inc(cXOR,c1-c0);c0:=c1;
end;
Memo1.Lines.Add(Format('XOR=%5d XCHG=%5d',[cXOR,cXCHG]));
end;
これでも 結果は XOR= 3589 XCHG= 3631 でAthronでは同じって結論でいいんじゃないの


161 :107:02/12/27 14:59
上と同じコードをx86-Famiky6と表示されるパソコンで走らせたら
  XOR= 4044 XCHG= 3756
って事で、若干 XCHG 命令が速いね。 

まあ当然の結果だけど。


162 :107:02/12/27 15:16
あと XOR の応用例

 abs(x) を CDQ /XOR /SUB で書けるように
 max(a,b) を書くのに分岐無しで書くのに応用出来る


163 :デフォルトの名無しさん:02/12/28 05:39
>>157
何を言っているのかわからないんだけど・・・。

> xorやmovによる交換も実質レジスタリネーミングされると
> 考えればパイプラインストールはほぼ発生してないはず。

そうなの??
mov はわからんでもないけど、xor が?

> xchg単体は mov/xor単体よりもずっと遅い
> という結果が出てくる。

単体で比較して何か意味あるの?
mov や xor に xchg 相当の事をやらせて初めて比較の意味があるんだけど。

164 :デフォルトの名無しさん:02/12/31 01:33
age
アセンブラの話よりも、本格的にトリッキーなコードキボンヌ

165 :デフォルトの名無しさん:02/12/31 04:04
トレッキーなコードなら書きますが、それが何か?


166 :デフォルトの名無しさん:02/12/31 05:57
int main(void){
 printf("VOYAGER マンセー\n");
 return 0;
}

167 :デフォルトの名無しさん:02/12/31 07:37
#define is_kanji1st(c) ((unsigned int) (c ^ 0x20) - 0xa1 < 0x3c)
シフトJISの1バイト目か判定(コピペ
外出だったらスマソ。

新年もトリッキーなコードが飛び交いますよう


168 :デフォルトの名無しさん:02/12/31 19:26
__machine {
 0x05, 0x0000ffff ;add eax, 0000ffff
}

機械語直打ちキター

169 :デフォルトの名無しさん:02/12/31 19:27
>>168
大晦日に萎えるソースコード持ってくるな・・・
前スレ嫁、そして初日の出を見ることなく氏ね

170 :デフォルトの名無しさん:02/12/31 19:51
__machine {
 0xff, 0xf1 ;push ecx
 0xe8, 0x40229833 ;call 40229833
}

(´∀`)あはは

171 :デフォルトの名無しさん:02/12/31 19:59
__machine {
 0x90
}

( ゚∀゚ )あっひゃっひゃっひゃ

172 :デフォルトの名無しさん:03/01/01 03:06
>>167
それは前スレで外出だったと思う。
どこからのコピペ?

173 :デフォルトの名無しさん:03/01/01 14:57
>>172
http://www.st.rim.or.jp/~phinloda/phin/phin9509.html


174 :デフォルトの名無しさん:03/01/01 18:14
>>173
NIFTYのどこかだと思ってたけど、元はFCだったか。

175 :デフォルトの名無しさん:03/01/03 02:12
>>167
マシン語の世界ではごくごく普通に使ってた計算式であり、
アルゴリズムなんだけど、高級言語に浸かってくると
やっぱり忘れてしまうわな、そういうの…。

#CMP一発で5分岐するとかって、あったなぁ。

176 :ツッコミ初め:03/01/03 16:04
>175
別にマシン語の世界じゃなくたって、一般的では。
境界線は自前で書いてるか、ライブラリ使ってるか、じゃないの?

177 :デフォルトの名無しさん:03/01/04 08:00
それがトリッキーじゃないって事は、こういうのもトリッキーじゃないのか。

大小によって -1,0,1を返す関数

type  TValueSign  =  -1..1;
function  CompSign(A,B:Integer):TValueSign;
asm
  CMP  EAX,EDX;  //A-B
  SETGE CL
  ADD  CL,CL
  DEC  CL
  CMP  EAX,EDX;  //A-B
  SETZ  AL
  DEC  AL
  AND  AL,CL
  CBW
  CWDE
end;

178 :デフォルトの名無しさん:03/01/04 08:29
VC6がそんなコードを吐いた気がする。


179 :デフォルトの名無しさん:03/01/05 05:51
#include <iostream>

void SwapXCHG(int& a, int& b)
{
asm {
mov eax, [a]
mov ebx, [b]
xchg eax, ebx
mov [a], eax
mov [b], ebx
}
}

void SwapXOR(int& a, int& b)
{
asm {
mov eax, [a]
mov ebx, [b]
xor eax, ebx
xor ebx, eax
xor eax, ebx
mov [a], eax
mov [b], ebx
}
}

180 :デフォルトの名無しさん:03/01/05 05:51
int RDTSC()
{
int i;

asm {
RDTSC
mov [i], eax
}
return i;
}

int main()
{
int a = 1, b = 2;
int c0, c1, cXCHG = 0, cXOR = 0;

for (int j = 0; j < 10; j++) {
c0 = RDTSC();
for (int i = 0; i < 1000; i++) SwapXCHG(a, b);
c1 = RDTSC();
cXCHG += c1 - c0;
c0 = RDTSC();
for (int i = 0; i < 1000; i++) SwapXOR(a, b);
c1 = RDTSC();
cXOR += c1 - c0;
}
std::cout << "XCHG = " << cXCHG << std::endl;
std::cout << "XOR = " << cXOR << std::endl;
}

181 :デフォルトの名無しさん:03/01/05 06:31
>>179,180は>>160のソースをC++にしたものだが、Pen4で実行してみた限りでは
両者の関数のクロック数にほとんど差がない。

>>177の比較関数もC++化して実行してみたが、単純なif文の方が約40%ほど
速かった。アセンブラによるトリッキーな書き方にはクロックの上でのアドバン
テージはないのだろうか。

182 :デフォルトの名無しさん:03/01/05 06:49
>>181
比較の場合はランダムデータですか?
最近のCPUは分岐予測が余程優れているのかな…。

183 :デフォルトの名無しさん:03/01/05 07:00
>>182
ランダムデータではないです。変数に値を入れておいて比較しました。
こんな感じ。

int main()
{
int c0, c1, cSETCC = 0, cIF = 0;
int a = 1, b = 2;

for (int j = 0; j < 10; j++) {
c0 = RDTSC();
for (int i = 0; i < 1000; i++) {
cmp1(a, b);
cmp1(b, a);
cmp1(a, a);
}
c1 = RDTSC();
cSETCC += c1 - c0;
c0 = RDTSC();
for (int i = 0; i < 1000; i++) {
cmp2(a, b);
cmp2(b, a);
cmp2(a, a);
}
c1 = RDTSC();
cIF += c1 - c0;
}
std::cout << "setcc = " << cSETCC << std::endl;
std::cout << "if = " << cIF << std::endl;
}

184 :デフォルトの名無しさん:03/01/05 07:04
あらら、ランダムデータにしたら、setccの方が30%ほど速くなりました。
分岐予測が働きにくくなるからでしょうね。

185 :デフォルトの名無しさん:03/01/05 11:00
ランダムデータとソート済みデータで速度が変わるんだねえ
どれらいのランダムネス(?)が境界になるのか知りたいところ

186 :デフォルトの名無しさん:03/01/05 11:10
>>185
P4だと、40個毎に乱数の系列を戻した時にほぼ同じタイムになるみたい。

const int N = 1000;

int cmp1(int& a, int& b)
{
int i;
asm {
MOV EAX,[a]
MOV EBX,[b]
CMP EAX,EBX; //A-B
SETGE CL
ADD CL,CL
DEC CL
CMP EAX,EBX; //A-B
SETZ AL
DEC AL
AND AL,CL
CBW
CWDE
MOV [i],EAX
}
return i;
}

int cmp2(int& a, int& b)
{
if (a < b) return -1;
else if (a > b) return 1;
return 0;
}

187 :デフォルトの名無しさん:03/01/05 11:11
int RDTSC()
{
int i;

asm {
RDTSC
mov [i], eax
}
return i;
}

int main()
{
int c0, c1, cSETCC = 0, cIF = 0;
int a[N], b[N];

for (int i = 0; i < N; i++) {
a[i] = std::rand(); // ここで比較用データをセットする
b[i] = std::rand(); //
if (i % 40 == 0) std::srand(0); // 乱数系列初期化用
}

188 :デフォルトの名無しさん:03/01/05 11:12
for (int j = 0; j < 10; j++) {
c0 = RDTSC();
for (int i = 0; i < 1000; i++) cmp1(a[i], b[i]);
c1 = RDTSC();
cSETCC += c1 - c0;
c0 = RDTSC();
for (int i = 0; i < 1000; i++) cmp2(a[i], b[i]);
c1 = RDTSC();
cIF += c1 - c0;
}
std::cout << "setcc = " << cSETCC << std::endl;
std::cout << "if = " << cIF << std::endl;
}

長文スマソ

189 :デフォルトの名無しさん:03/01/05 11:16
いや、勉強になった。
少し前まで、分岐予測ミスのペナルティは大きくて 分岐なしが平均的には余程速かったのになあ

190 :デフォルトの名無しさん:03/01/05 11:26
グッジョブ!
しかしこの比率ってCPUの世代で変わったりするのかな・・・

191 :デフォルトの名無しさん:03/01/05 11:28
>>189
分岐履歴バッファがCPU内部にはあって、何重もの入れ子になった
ループの分岐を予測できるらしいですね。
P4のような深いパイプラインを持つCPUでは不可欠の機構なので
相当念入りに作ってあるようです。

P3やAthlonの結果も知りたいのですが、どなたか試してみていただ
けませんか?

192 :デフォルトの名無しさん:03/01/05 17:31
AthlonXP1800+、VC++6にてテストしてみた。
概ねcmp1のほうが速いですが、評価順や最適化の有り無しでも
結果が変わるようです。(i % 40)の部分はほぼ影響なかった。
正確に測るには関数内に_asmでRDTSC入れてDWORD境界の
対策をしないと駄目かも知れず。
あ、最適化するとcmp2(if 〜 else if 〜)の関数内にあるジャンプ
命令は1個ですたw

193 :デフォルトの名無しさん:03/01/05 18:26
あ、DWORD境界ってのはRDTSCの返り値がループした時の事です。

194 :デフォルトの名無しさん:03/01/05 18:42
cmp1ってローカル変数に代入するから
こんな小さなコードだと少しはロスがあると思うわけ。
(フルアセンブラや、gccやbccのようにレジスタを直接返せれば別だけど)

ってゆーかさ、"トリッキーなコード"を名乗るんだったら、
せめてこの程度までは最適化してから比較しようよ。

と言ったものの、あまり詳しくないんで、
見た目が最適化されただけで、内部的なクロック数は増えてるしれない。

int cmp1(int a, int b)
{
 asm {
  mov eax, a  // 引数をレジスタ渡しだと・・・
  cmp eax, b  // 
  setl al
  setg cl
  neg al
  xor al, cl
  cbw
  cwde
  mov a, eax  // <-これがじゃま
 }
 return a;
}

195 :デフォルトの名無しさん:03/01/05 19:13
>>194
SETxx はフラグに影響を与えなかったっけ?

196 :デフォルトの名無しさん:03/01/05 19:29
SETccはフラグに影響しない(マニュアルに書いてある)

コンパイラはフラグを「比較直後」以外に使うのがうまくないんだよね。
その後で並べ替えることはあっても。
だから、アセンブラレベルでなら、add/subの代わりにleaを用いてフラグを維持し、
それから条件を調べる(jmp等)って方法なんかもでてくるわけさ。
もちろん、よほどクリティカルな部分でない限り、意味は無いけどね。

よく考えたら、>>194はxorではなくorを使ってもいいんだけど、
xorの方が意味が分かりにくい==トリッキーってことで許して。

で、ほぼ同じロジックでCで書くとしたら
int cmp2(int a, int b)
{
 return (a < b) | -(a > b);
}
だね。

197 :デフォルトの名無しさん:03/01/05 20:00
そうか。intelから資料ダウンロードして確認したよ。
持ってた本に実行後にフラグが変更されてるような用例載ってたから勘違いしてた。

じゃあ1ステップ短く出来るよ

type  TValueSign  =  -1..1;
function  CompSign(A,B:Integer):TValueSign;
asm
  CMP  EAX,EDX;  //A-B
  SETLE AH
  SETGE AL
  SUB  AL,AH
  CBW
  CWDE
end;

198 :デフォルトの名無しさん:03/01/05 20:06
せっかくいい感じにベンチマークできてたのに
194から急に厨臭くなった・・・

199 :デフォルトの名無しさん:03/01/05 20:10
cbw+cwdeとmovsxはどっちがいいのかな?

>>197を読んで思い出したけど、
似たようなロジックは半年くらい前にC言語スレで見た(書いた)気がする。
減算結果の最上位bitをシフトしてxorとるやつ。

とここまで書いて、その時見たのは「aとbの符号が一致しているかを返す」
だったのを思い出した。
そういうのがあったからxor使っちゃったんだな(もちろん、subの方が良いけど)

200 :デフォルトの名無しさん:03/01/05 20:21
>>198
ん?ベンチマーク続けてかまわないんじゃないの?
一つのスレッドで複数の話題が進行するなんてよくあることだし。

要は、分岐予測があたることに期待した単純なコードと
分岐予測がはずれる可能性に備えて少し複雑なコードで
CPUやデータのばらつきによって、どちらが良いか、どのあたりが分岐点になるのかでしょ?
実際、現在のCPUでは分岐予測ミスやメモリアクセスなどの
ペナルティを減らす方がはるかに重要だし。

201 :デフォルトの名無しさん:03/01/05 20:25
いや、急に見た目最適化とかステップ数とか
そういうのが当てにならないにもかかわらず
アナクロな方向になってあきれただけ

202 :デフォルトの名無しさん:03/01/05 20:41
一つの命令自体のクロック数はあまり意味はないけど、
・メモリアクセスがない
・分岐がない
・複雑な命令がない
・依存関係のある命令が少ない
場合ならば、充分意味があるよ。

少なくとも俺は、
「両方Cで書いて分岐の有無によるテスト」か
「両方アセンブラで書いて分岐の有無によるテスト」
にしないなら、
「片方をC、片方をアセンブラで書いてどちらも分岐命令を使う」
「片方をC、片方をアセンブラで書いてどちらも分岐命令を使わない」
でなければ、あまり意味はないと思っているけどね。

出来れば、全てアセンブラでアラインも揃え、
分岐の有無による差を見たいけどね。

203 :デフォルトの名無しさん:03/01/05 20:57
> 場合ならば、充分意味があるよ。

単なる思い込みコードをベンチマーク結果なしにみせつけられてもねえ。

204 :デフォルトの名無しさん:03/01/05 21:25
そうだね。
このスレに書く"トリッキーなコード"はベンチマークがなきゃ意味無いよね。

205 :デフォルトの名無しさん:03/01/05 21:31
速度のためのトリックならベンチマーク必須だね。
コード量削減のためならバイト数の計測。

他人を驚かすのが目的なら・・・どうしよう

206 :デフォルトの名無しさん:03/01/05 21:39
>cbw+cwdeとmovsxはどっちがいいのかな?
あ! 忘れてた。 MOVSX があったんだ。

そりゃMOVSX1命令の方が短いでしょ

type  TValueSign  =  -1..1;
function  CompSign(A,B:Integer):TValueSign;
asm
  CMP  EAX,EDX;  //A-B
  SETLE AH
  SETGE AL
  SUB  AL,AH
  MOVSX AX,AL
end;

207 :デフォルトの名無しさん:03/01/05 21:56
どーーーしても「コードを見れば明らか」と納得できない人約一名がいるみたいなので
ベンチマーク取りましたよ。
test1が>>183の外ループを10倍したもの
test2が>>187-188の外ループを10倍したもの
cmp1が>>197の前後にロードとストアを入れたもの
cmp2が>>186のcmp1の引数を参照にしなかったもの
呼び出し規約はcdeclで。

test1
cmp1 = 4943201
cmp2 = 7133229
test2
cmp1 = 1677185
cmp2 = 2230045

ま、こんなもんでしょ。
ロード/ストア/スタックフレーム操作/callが入るからそうそう極端な差はつかないね。

208 :207:03/01/05 22:00
あ、アーキテクチャはP6ね

209 :デフォルトの名無しさん:03/01/05 22:07
おう、厨房から脱出した人、おめでとう

210 :デフォルトの名無しさん:03/01/05 22:14
安心しろ。
「明らか」な結果をわざわざ測定するのは今回だけ。学生実験とは違うから。
まあ雪で出かけられない中、良い暇つぶしになったよ。

211 :デフォルトの名無しさん:03/01/05 22:16
結果が明らか?
んなアホな

212 :デフォルトの名無しさん:03/01/05 22:20
>>186より>>197>>206が速いのは(わかる人にとっては)明らかだよ。

もちろん、何十年後かのアーキテクチャでもそうだとは言い切らないけど、
今後10年の間は明らか。
逆転するようなことがあっても、その時代にはx86(IA-32)は寿命を終えている。

213 :デフォルトの名無しさん:03/01/05 22:21
明らかな理由は>>202の前半に書いたけど、理解できなかったんだろうね。

214 :デフォルトの名無しさん:03/01/05 22:22
うーん、厨房は死んでも直らないとはこのことか・・・
残念。

215 :デフォルトの名無しさん:03/01/05 22:25
おもしろいからあげ



216 :デフォルトの名無しさん:03/01/05 22:27
うん、俺はベンチマークも提示できないような厨房だから
煽りにも精一杯反応しちゃうよ。

ねー、ぼくちゃんは厨房じゃないんでしょ?
煽りに反応しちゃだめでしょ。

217 :デフォルトの名無しさん:03/01/05 22:29
腐ってきた。194と197どっちが腐らせたんだ。

218 :デフォルトの名無しさん:03/01/05 22:29
この程度で煽りと思ってしまうのはまずいと思う。
単なる指摘でしょう。

そういやIA-32って今年で18周年だね。

219 :デフォルトの名無しさん:03/01/05 22:40
>198 >201 >203 >205 >209 >211 >214

220 :デフォルトの名無しさん:03/01/05 22:41
なるほど、いきなり厨臭くなったことを指摘してくれたんだね。どうもありがとう。

221 :デフォルトの名無しさん:03/01/05 22:42
非常に重要な指摘でした
有意義な時間を過ごせました

222 :デフォルトの名無しさん:03/01/05 22:46
そうだ、>>198さんは
俺が>>202の後半で指摘した「ベンチマークは測定条件を揃えて」ってのは
放置しちゃったのかな?
>>198で、すごくベンチマークが楽しみそうだったのに。

223 :デフォルトの名無しさん:03/01/05 23:14
まあ、測定条件を揃えずに、単に「分岐予測による効果で結果が変わる」ことだけなら
>>188まででわかったんだから
AthlonもP3も関係ないし、どちらが何%速いとか
どこで逆転するとかの報告は必要ないな。

確かに、アセンブラの方を最適化したから厨房臭かったかもね。
むしろ、「これ↓の結果を比較しろ」と書いた方が良かったか?
int cmp1(int a, int b) {
 return (a > b) - (a < b);
}
int cmp2(int a, int b){
 if (a < b) return -1;
 else if (a > b) return 1;
 return 0;
}

最後に付け加えとこ。
>>177(以降)はSETccを使って分岐をなくしているけど、
CMOVでも同じ結果が出てる。
少なくとも、現存のx86アーキテクチャは
 分岐予測成功 > CMOV >>> 分岐予測失敗
になってる。

224 :デフォルトの名無しさん:03/01/05 23:21
>少なくとも、現存のx86アーキテクチャは
> 分岐予測成功 > CMOV >>> 分岐予測失敗
>になってる。

P3からP4になって、さらに強まった気がするんだけどどうかなあ

225 :デフォルトの名無しさん:03/01/06 01:58
俺には難しいけどいいスレっぽいな。
がんばれ!

226 :デフォルトの名無しさん:03/01/06 07:43
へえ CMOV か Pen2以後で使えるんだね。

227 :デフォルトの名無しさん:03/01/06 12:58
なるほど、>>206さんのようにすると、ランダムな比較をしても速いね。
ステップ数が少ないので、if文では完全な規則性のある数を比較した場合
以外ほとんどかなわない。

CMOVを使ったプログラムでも検証してみます。

228 :デフォルトの名無しさん:03/01/06 13:19
なるほど、CMOVccでもSETccと同等の速度が出るね。CMOVがイミディエート値
をロードできると思ってたけど、だめなのね。

int cmp1(int& a, int& b)
{
static int one = 1, mone = -1;
int i;
asm {
MOV ESI,a
MOV EDI,b
MOV EAX,0
CMP ESI,EDI;
CMOVL EAX,mone
CMOVG EAX,one
MOV i,EAX
}
return i;
}

229 :デフォルトの名無しさん:03/01/06 13:36
>>228
CMP じゃなlくて SUB にすれば 引算結果のゼロを使えるから1ステップ短くなるよ


230 :デフォルトの名無しさん:03/01/06 13:44
デバッガで追いかけたら、次の部分が正しいコードに展開されてなかった。

MOV ESI,a
MOV EDI,b

int&a, int& bとなっているので、aとbはポインタを与えてしまう。だからこれは

MOV ESI,a
MOV ESI,[ESI]
MOV EDI,b
MOV EDI,[EDI]

と書かなければならない。このような不都合を避けるため、intの参照ではなく
値で渡す事にした。if文の方も値で渡すようにしたのだが、意外とif文が速くなっ
た。乱数の発生系列の初期化を70個毎にしないとCMOVccやSETccが負けて
しまう。

231 :デフォルトの名無しさん:03/01/06 13:45
>>229
それはなかなかトリッキーですね!早速やってみます!

232 :デフォルトの名無しさん:03/01/06 13:51
>>229
このようにしてみました。規則的なifの速度にはかなわないけど、不規則な
ifに対しては、乱数の初期化を10個毎にしても勝てます!(Pentium4)

asm {
MOV EAX,a
MOV EBX,b
SUB EAX,EBX;
CMOVL EAX,mone
CMOVG EAX,one
MOV i,EAX
}

233 :デフォルトの名無しさん:03/01/06 14:15
あんまり短いコードでベンチマークしても意味がないと思うけどなあ

分岐なしに書けるなら、多少冗長に見えても、使った方が全体のパフォーマンスが上がる事がおおいよ。
年々大きくはなっても、分岐ターゲット・バッファ(BTB)はやっぱり有限だからさ。

234 :デフォルトの名無しさん:03/01/06 14:56
>>233
大規模なプログラムだと、分岐の過程は一般的にランダムだから、分岐フロー
を無くすようなプログラムが効果的でしょうね。ただ、短いコードでないと、分岐
無しで動作するようなプログラムを書く事は非常に難しいでしょうけど。

235 :デフォルトの名無しさん:03/01/06 15:08
>>234
いやそうじゃなくて、再利用度の高い一部の関数とかを分岐無しが可能なら、出来る時に書いておけば
全体のパフォーマンスが上がるだろうって事。
たとえ、その関数だけ評価して if 文よりパフォーマンスが悪くても、

もちろん重い処理の内側のループを書くような場合は別だけどさ

236 :デフォルトの名無しさん:03/01/06 15:12
>>235
ああなるほど、BTBをなるべく消費しない関数が書けるなら書いておこうって
事ですね。納得。その分別の箇所でBTBが有効活用できるって事か。

237 :デフォルトの名無しさん:03/01/06 17:26
SSE2命令を使ったトリッキーなプログラムってありますか?

238 :デフォルトの名無しさん:03/01/06 23:03
大規模なプログラムでそんなこと気にする人っているんかいな

239 :デフォルトの名無しさん:03/01/07 02:57
SE を使ったトリッキーなプログラムってありますか?

240 :デフォルトの名無しさん:03/01/07 05:02
>>232
キャッシュにヒットしないと遅い予感
って、そんな場合は、ほとんど意味が無いから置いといて
Pen4はCMOVccのレイテンシがマニュアルに見当たらないので
知らなかったけど結構早かったんですね…
でも、おそらくP6系ではSETccの方が早いはずので
P6系を持ってる方はレッツチャレンジ♪
(と言っても、あまり差は出ないと思うけど…)

ついでに両方の値をレジスタに入れる必要は…
asm {
  MOV EAX,a
  SUB EAX,b
  CMOVL EAX,mone

}

241 :デフォルトの名無しさん:03/01/07 16:10
>>239
SEにプログラム作らせる事自体がトリッキー

242 :デフォルトの名無しさん:03/01/08 17:23
なんかみんなスゲー。仕事でプログラムやってる人??
年齢もしりたいw

243 :デフォルトの名無しさん:03/01/08 18:46
いつの間にか前スレが埋められてる・・・
2年間、もってくれるかなと思ってたけど、
それまでに落ちちゃうかなぁ。

244 :IP記録実験:03/01/08 21:27
IP記録実験
http://qb.2ch.net/test/read.cgi/accuse/1042013605/

1 名前:ひろゆき ◆3SHRUNYAXA @どうやら管理人 ★ 投稿日:03/01/08 17:13 ID:???
そんなわけで、qbサーバでIPの記録実験をはじめましたー。

27 名前:心得をよく読みましょう 投稿日:03/01/08 17:20 ID:yL/kYdMc
SETTING.TXT管轄でないということは全鯖導入を視野に、か?

38 名前:ひろゆき ◆3SHRUNYAXA 投稿日:03/01/08 17:22 ID:rLfxQ17l
>>27
鋭いです。

73 名前:ひろゆき ◆3SHRUNYAXA 投稿日:03/01/08 17:27 ID:rLfxQ17l
>ところで、IPが抜かれて何か今までと変わることってあるのでしょうか?
・今までより、サーバが重くなる。
・裁判所や警察からの照会があった場合にはIPを提出することがある。

245 :デフォルトの名無しさん:03/01/08 23:38
age

246 :デフォルトの名無しさん:03/01/09 00:19
全レスです。

247 :デフォルトの名無しさん:03/01/09 00:27
あこがれのヒモ生活のためにがんばってもらいたいものです。
>>10

248 :デフォルトの名無しさん:03/01/09 00:49
>>212
     llllllllllll                               lllll
          lllllll                              lllll
        lllll                                llllll
    lllll  llllllllll  llllllllll                        lllll
  lllll      lllll    llllllllll    lllllllllllllllllllllllllllllllllll   lllllll
 lllll      llllllllll    llllllllll                  lllllllllllllll      lllll
llllllllll      llllllllll  llllllllll                  lllll    lllll  lllllllll
        llllllllll                          lllll      llllllll

       ∧_∧  ∧_∧  ∧_∧  ∧_∧
      ( ´_ゝ`) ( ´_ゝ`) ( ´_ゝ`) ( ´_ゝ`)
      ∧_∧ ) ∧_∧ )∧_∧ )∧_∧ )
     ( ´_ゝ`) ( ´_ゝ`) ( ´_ゝ`) ( ´_ゝ`)
   ∧_∧ ) ∧_∧ ) ∧_∧ )∧_∧ )
   ( ´_ゝ`) ( ´_ゝ`)  ( ´_ゝ`) ( ´_ゝ`)/|
  (____)  (____) (____) (____)
/   ./|./   /|./   /|/   /|
| ̄ ̄ ̄|/| ̄ ̄ ̄|/| ̄ ̄ ̄|/| ̄ ̄ ̄|/|
|| ̄ ̄ ̄|| || ̄ ̄ ̄|| || ̄ ̄ ̄|| || ̄ ̄ ̄||


249 :デフォルトの名無しさん:03/01/09 00:53
無限にログを残してるサーバ管理者っていないと思います。

250 :デフォルトの名無しさん:03/01/09 01:13
>>352
ひろしま必死だなっと・・・

251 :デフォルトの名無しさん:03/01/09 01:27
>>475 大収穫じゃん

252 :デフォルトの名無しさん:03/01/09 02:01
俺のプロバ当ててみろ!!!!!!!!

253 :デフォルトの名無しさん:03/01/09 02:31
>>242
244 からの惨状はお前のせいだ。

254 :デフォルトの名無しさん:03/01/09 02:57
もう2ちゃんねるも終わりです。
ほかのところいこーぜ

255 :デフォルトの名無しさん:03/01/09 03:42
>>158
IPとられるとられないにかかわらず、重大な決意で告発する人はいると思うけど。
そういうひとが保護されるかどうかが問題だわなー。

ウソ書いてひとに迷惑かける奴は保護される価値がないと思うけれども。

256 :デフォルトの名無しさん:03/01/09 12:39
匿名とは、自分が提示する情報だけで勝負することをいうので、

257 :デフォルトの名無しさん:03/01/09 18:03
======2==C==H======================================================

         2ちゃんねるのお勧めな話題と
     ネットでの面白い出来事を配送したいと思ってます。。。

===============================読者数: 138720人 発行日:2003/1/9

年末年始ボケがそろそろ収まり始めた今日このごろのひろゆきです。

そんなわけで、年末に予告したIP記録ですが実験を開始しています。

「2ちゃんねる20030107」
こんな感じで各掲示板の最下部に日付が入ってるんですが、
20030107以降になってるところはログ記録実験中ですー。

んじゃ!

────────────────────────Age2ch─
■この書き込みは、Age2chを使って配信されています。
────────────────────────────
Keep your thread alive !
http://pc3.2ch.net/test/read.cgi/software/1041952901/l50
────────────────────────────

258 :デフォルトの名無しさん:03/01/09 23:53
記念かきこ

259 :デフォルトの名無しさん:03/01/10 08:46
あめぞうという昔旺盛を極めた掲示板は「誹謗・中傷・アダルトお断り」の文字を書き込んだ
事が原因の1つとなって潰れたが、いまの2chは「誹謗・中傷・密告お断り」というのを出したのと
同じ事なんだよなあ、、、

260 :デフォルトの名無しさん:03/01/10 10:07
http://courtdomino2.courts.go.jp/kshanrei.nsf/$DefaultView/2075F93E3210745849256BED0030F3EF?OpenDocument

この判決文のなかに「内容証明がなんとか」ってのは書いてあるかってことだな

261 :デフォルトの名無しさん:03/01/10 10:46
>訴状と内容証明の区別ができてる?
訴状だろうと内容証明だろうと、
問題は「掲示板に名誉毀損が書いてあると知りえた時点で、
削除する義務がある」ってことなんじゃないすか?

262 :デフォルトの名無しさん:03/01/10 11:15
>>655-656
http://qb.2ch.net/test/read.cgi/accuse/1041540580/11n

11 :心得をよく読みましょう :03/01/03 05:56 ID:hY/1UvLC
438 名前:名無しさん@お腹いっぱい。 投稿日:03/01/03 05:29 ID:uI8o9EyD
http://pink.bbspink.com/test/read.cgi/ascii2d/1039712295/
このスレは危険。 開くと無限にIEが開くよ。

レスの本文中にJavaScriptが書ける技術があるらしいね。
とりあえず2ch側で対策がとられるまでの間は
kageのngword.txtに <script language="JavaScript">
をNGワードとして登録しておいた方がいいかも。

263 :デフォルトの名無しさん:03/01/10 12:02
>>169-170>>172>>185>>187-188>>190-191>>193>>204-207
>>228-230>>246-247
>>255>>261-262>>264-265>>271>>274-275
>>295-296>>306-307>>309>>318-321>>323

264 :デフォルトの名無しさん:03/01/10 12:30
挙手による多数決は最大の愚行!!
匿名性が失われ自分に反対する者が誰かは
わかるのに小数派には反論さえ許されない
最悪のシステム!!

もしも常に特定の人物と
意見が対立し 常に片方だけが意思を
抹殺されたら…

それが続けば必ず集団は決裂する!!

265 :デフォルトの名無しさん:03/01/10 13:24
じゃ、winnyでニュー速のスレ立てるか?

266 :デフォルトの名無しさん:03/01/10 15:45
鳥カエレ!は今まで言ったこともあるが
女子大生カエレ!は心情的に言いにくいじゃないのぅ!
(`ε´)プー

267 :デフォルトの名無しさん:03/01/10 17:12

荒しのヤシは別に困らないだろ?
それよりも貴重な情報が流れなくなる気が、、、
ネタでした と言ってほしいぃ

268 :デフォルトの名無しさん:03/01/10 23:33
2chのIDてIPを変換してるんだっけ?
だったら、全板強制IDにして暗号キーだけ保存しておけばいいんじゃないの?

269 :デフォルトの名無しさん:03/01/10 23:41
終わったな
ま、ひろゆきは何も悪いことはしないわけだが

270 :デフォルトの名無しさん:03/01/11 00:56
ボルタレンじゃなくて??

271 :デフォルトの名無しさん:03/01/11 01:07
誰か
IDにIPを出すことを要求します
ってスレ立てておながい

272 :デフォルトの名無しさん:03/01/11 10:29
    ∧_∧    / ̄ ̄ ̄ ̄ ̄
    ( ´∀`) < なんでだろ〜!
  ⊂⌒  て)   \_____
    (  、___つ
    )  )
    し'        ∧_∧     / ̄ ̄ ̄ ̄ ̄ ̄ ̄
             ( ´∀` )   < なんでだろ〜♪
          / ̄ヽ/,― 、\ o。。。\_______
          | ||三∪●)三mΕ∃.
          \_,へ--イ |   ゚ ゚ ゚
             (_)(_)


273 :デフォルトの名無しさん:03/01/11 11:03
======2==C==H======================================================

         2ちゃんねるのお勧めな話題と
     ネットでの面白い出来事を配送したいと思ってます。。。

===============================読者数: 139038人 発行日:2003/1/10

なにやら、連日メルマガだしてるひろゆきです。

そんなわけで、ログ記録実験ですが、いちいちサーバ指定するのが面倒なので、
全部のサーバに入れてみました。

重くなって落ちたりしてもご愛嬌ってことで。。。

んじゃ!

────────────────────────Age2ch─
■この書き込みは、Age2chを使って配信されています。
────────────────────────────
Keep your thread alive !
http://pc3.2ch.net/test/read.cgi/software/1041952901/l50
────────────────────────────

274 :デフォルトの名無しさん:03/01/11 11:54
変なことって例えば?

275 :デフォルトの名無しさん:03/01/11 12:30
明日もそれ以降も何もしません

276 :デフォルトの名無しさん:03/01/11 13:29
そんなことをしようとするより
鯖をクラックするだろう

277 :デフォルトの名無しさん:03/01/11 15:40
矩形の問題はどうなったのか気になったり気にならなかったり

278 :デフォルトの名無しさん:03/01/11 16:42
まぁなんだ

「ひろゆきよ ラウンジが重いんだが・・・と電話しまくって即閉鎖」

が一番早そうだな(藁

279 :デフォルトの名無しさん:03/01/11 16:51
2chで内部告発的な事をするリスクが大きくなるのかな?
発信元がわかるんで、告発された側が「よーし金でねじ伏せちゃうぞー」
とか言って裁判でも起こしまくって。
そんな状況はガクブルだから、面白そうな(真実である事が前提の)投稿は、減る?のかな?
考え過ぎ?って言うか見当違い?どうだ?どうなんだ?

280 :デフォルトの名無しさん:03/01/11 23:41
                    ,,,,,,,,,,,,,,,,,,,,,,,,,,,,
            ,,--―'''""`ヽ'         ̄`ヽ、
           /        ヾ  /        ~`ヽ
         /           ヽ;:/""""ヾ   ミ  ヽ
        /        ;:;;:::''''""""       \     i
      /        /               ヽ  ヾヽ
      /     / / ;/                ヾ   ヽ
     /        ;:;:ヽ             ,,,,;;::'''''ヽ  ;:|
     i          /  ,,,,;;:::::::::::::::         ヽ  ヽ
     |      |   |  "        ::::   /\ ヾ  ヽ
     |     |  ヾ |       /\  ::::::.  :     |  ;:|
     |         ;:|          : :::::::  : .、    |  :|
      |         ヽ         ( ,--、 ,:"'     | /|!
      |      ヽ ヾ                   |;:/
      |         |         __,-'ニニニヽ   /|
       ||       `、ヽ         ヾニ二ン"   /;:|
        |       ヽ \               /ノ
        |        i  `ー-::、_        ,,..-'|ヽ
         ヽ;:;:;:;:   ;:人      `ー――'''''"~ / ヽ
            \;:;:;:;:/  `ー-、         ,.-'"   \ー-、
           ,.-'" :/      \      ,.-''"     |
         /    !        ~>、,.-''"        |
    ,,..-‐'''""      ヾ    ,.-''"――――-、      /


            (^^)は山崎渉であると見抜ける人でないと
           (掲示板を使うのは)難しい(^^)

281 :デフォルトの名無しさん:03/01/11 23:52
あと約1500

282 :デフォルトの名無しさん:03/01/12 02:30
バガンっっ!!!!!ズサッ ガッ ギュィィ ゴッググモッッ雨雨
グモッチュチュイチュイチュイーーーーーーーーーーーーーーーーーーーんチュイチュイチュイチュイ――ン
罵ッゴんばっこんばっ婆ッゴんばぎゅブギュ罵ぎゅぎゅきゅ ぼごんぼごんぼごんぼごん
跋扈ン跋扈ン跋扈ンバッカンバッカン馬鹿馬鹿婆きゅうううーー
ギュ気ギュ気ギュ気いい疑義一ギいいっ ギュぎゅうぎゅううう ぶじゅぶじゅぶじゅ
  ききっーーぃ きい ゴットン
となって、ミンチ轢肉になって成仏してしまったそうです。

尚、貨物はフルパワー・全快で走行していた長い編成だったので、凄まじい勢い
で轢断・繊断(物性物理学の運動エネルギー・車輪とレールの轢断機により)され
15歳の中3は、肉片と化したそうです。
 お気の毒ですが、この肉片は荼毘に附して、灰にし、土に帰します。あしからず
ご了承くだされい。


283 :デフォルトの名無しさん:03/01/12 10:03
ああ、昨日のあったやつか。一応乗ったんだね

284 :デフォルトの名無しさん:03/01/12 10:06
そうだね。
今なら勝つ確率高いしね。
しかも何百ももらえるしw

285 :デフォルトの名無しさん:03/01/12 20:51
http://www.liquidgeneration.com/sabotage/vision_sabotage.swf

286 :デフォルトの名無しさん:03/01/12 20:54
>59K+TtJ+
ややこしいからそのトリップ使うな。

今回の裁判の話と今後起こりうる訴訟は全然別の話になるだろうから、
(プロバイダ責任制限法と削除システムの変更がある)
ごっちゃにして話をするのは無意味。

287 :デフォルトの名無しさん:03/01/12 21:02
今後sports3鯖は定期的にhtml化されるの?

288 :山崎渉:03/01/13 18:42
(^^)

289 :デフォルトの名無しさん:03/01/13 22:41
4nd にびっくりすますた。

290 :デフォルトの名無しさん:03/01/15 07:25
多数決
(a|b)^(a|c)^(b|c)

291 :山崎渉:03/01/16 02:56
(^^)

292 :デフォルトの名無しさん:03/01/19 10:59
age
アセンブラネタきぼん。実験しますので

293 :デフォルトの名無しさん:03/01/19 11:32
今更だが、>>132をやってみました。
Pentium4 2.53GHz + DDRSDRAM(PC2100)

func1 = 1286
func2 = 1286
func3 = 1287
func4 = 2568

mov, xor, xchg はほとんど差がありませんでした。Pentium3とは
傾向が違うようです。

294 :デフォルトの名無しさん:03/01/19 18:43
>>293
#define LOOP 500000

#define LOOP 50000000
でキボンヌ。

295 :デフォルトの名無しさん:03/01/19 23:19
>>294
どうぞ。
func1 = 128540
func2 = 128966
func3 = 128906
func4 = 306264

296 :デフォルトの名無しさん:03/01/20 03:18
僅差で mov > xchg > xor >>>> pop でつか。
誤差はあるかも知れないけど・・・。

P3 では xchg > mov >> xor >>>> pop だった気がする。

297 :デフォルトの名無しさん:03/01/20 22:56
誤差だろ。

298 :デフォルトの名無しさん:03/01/21 06:50
じゃあ
#define LOOP 4000000000
でキボンヌ。

299 :デフォルトの名無しさん:03/01/21 19:09
>>298
どぞ。
push/popだけ異常に遅いですな。

func1 = 10361072
func2 = 10327317
func3 = 10335487
func4 = 27160516

300 :デフォルトの名無しさん:03/01/21 21:20
xor が速いように見えるな。

301 :129-132:03/01/21 22:57
>>293-300
長時間かかるとOSのタイムスライスなども気になるので
LOOP回数はそれほど長くないほうがいい。
PerfomanceCounterの制度は十分に高かったはず。。。

func1 = func2 = func3 > func4
と考えて
mov*3 = xor*3 = xchg*1 = (push*2/pop*2)*2
かな?

ちなみに最初は dec ecx & jnz の代わりに loop を
使ってみたんだが loop はかなり遅かった…。びっくり。

Athlon系やCrusoe系の結果も興味あるところ…。

302 :デフォルトの名無しさん:03/01/21 23:21
>>301
Pentium4はALUがPentium3と違うアーキテクチャのようだし、
トレースキャッシュとかいうよく分からない機構を使っていたりで、
単純ループには強いみたい。

loop命令使って書いてみましょうか。そしたらmovのセクションを
dec & jnz と loopにしたものとで比較。

303 :デフォルトの名無しさん:03/01/21 23:22
そう言えばOSはWindowsXP使ってます。push/popのようなメモリアクセス
が発生する命令はOSの影響があって遅くなると聞いたことがあるのです
が本当でしょうか?

304 :デフォルトの名無しさん:03/01/21 23:26
func1がdec & jnz で、func11がloop命令を使いました。
確かに遅いですね。

func1 = 1354
func11 = 1927

何かこのスレトリッキーなコードでなくてアセンブラの最適化スレ
見たいになってきたね(w

305 :デフォルトの名無しさん:03/01/21 23:36
>>303
push/popなどのスタックをアクセスする命令は、
スタックセグメント経由で行われるため、OSの設定によっては
遅くなる可能性がある。



嘘だけど。

306 :デフォルトの名無しさん:03/01/21 23:41
>>305
WindowsNTの古いバージョンでは、スタックアクセスが発生すると
いちいち割り込みがかかってすごく遅くなってたようですよ。

WindowsXPもNT系なので、push/popの速度が95系とは違うのではない
かと思ったのです。でもPentium4でMeとか使ってる人はさすがに少ない
だろうな。

307 :デフォルトの名無しさん:03/01/21 23:50
スタックが伸びるときに例外出すのは分かるけど、
一度ページインしたら関係ないような・・・古いって3以前?

308 :デフォルトの名無しさん:03/01/21 23:51
Pen4では、レジスタの入れ替えにpush/popは使わず、
それ以外を使え、ってことですね。

ベンチマークするといろいろ分かって面白い。

309 :デフォルトの名無しさん:03/01/22 00:15
>>307
NT2だったかも。それでCALL命令とかも異常に遅くて、NT3で直された
というような話をどこかで聞いた。
>>308
Athlonではどうなんでしょう?かなり優れたアーキテクチャらしいけど。
Pen4はALUが倍速動作しているので、メモリアクセスがないと強いみたい。

310 :デフォルトの名無しさん:03/01/22 00:35
push/popってメモリに反映させる必要があるだろうから、
メモリ/キャッシュのインターフェースが異常に賢くないかぎり
同じぐらいの結果じゃないの。

NT2か・・・ネタにしては陳腐だったな。

311 :デフォルトの名無しさん:03/01/22 09:12
NT2 ってなんですか?

312 :デフォルトの名無しさん:03/01/22 14:20
>>311
ありません。

313 :311:03/01/22 19:46
>>312
だよね。勘違いじゃなかった。

314 :山崎渉:03/01/23 20:10
(^^)

315 :デフォルトの名無しさん:03/01/31 02:25
>>106 から引きずってる話題だが、肝心なこと忘れてないか?
XOR は両辺が同値だったら 0 になってしまうぞ。
そのチェックはどうするんだ?

316 :デフォルトの名無しさん:03/01/31 02:38
>>315
>>106だけ読んでも何の話かよく分からないので
少し詳しくお願いします

317 :デフォルトの名無しさん:03/01/31 03:13
>>316
「から引きずってる」 って書いたんだから、それより後ろも読んでくれよ・・・。

要約すると、2 つのレジスタの値を交換するには何が最も速いかという話。
候補としては、
1. 別のレジスタを介して MOV で交換。
2. XOR A, B、XOR B, A、XOR A, B で交換。
3. XCHG で交換。
4. スタックを介して POP と PUSH で交換。
で、スタックを使う 4 は論外に遅く、他は CPU 等によって変動するが
僅差という結論だった。

んでもって、2 の XOR は実は問題あるんじゃないかと 315 に書いたの。

318 :デフォルトの名無しさん:03/01/31 03:17
>>316
ネタでしょ
アセンブラ(じゃなくても良いけど)でeaxとebxの値を入れかえる時に
↓のようにしてeaxとebxの値を入れかえる
xor eax, ebx; eax = (eax^ebx)
xor ebx, eax; ebx = ebx^(eax^ebx) → eax^ebx^ebx → eax^0 → eax
xor eax, ebx; eax = (eax^ebx)^eax → eax^eax^ebx → 0^ebx → ebx
この時eaxとebxが同じ値だと一度0になってしまうので
>>315の主張が正しいように見えるが、それに同意すると
最終的には、↓のように問題無く入れ替わる事を指摘される罠
xor eax, ebx; eax = 0
xor ebx, eax; ebx = ebx^0 → ebx(=eax)
xor eax, ebx; eax = 0^ebx → ebx(=eax)

319 :デフォルトの名無しさん:03/01/31 03:22
>>318
理解した。すまそ

320 :デフォルトの名無しさん:03/01/31 23:48
xchgがmov・xor三回とほぼ同じというのは
内部で三命令に分解されちゃってるということなんでしょーか。

321 :デフォルトの名無しさん:03/01/31 23:56
>>317
C言語でスワップを XOR で書くとまずいを引きずってるのかな。
あれは同じ値ではなくて同じアドレスの時まずいってやつだから。

>>320
P6以降は内部でMicroコードに分解されているので有り得るかもしれませんね。

322 :デフォルトの名無しさん:03/01/31 23:57
>>320
http://www.agner.org/assem/pentopt.zip
によると、レジスタ-レジスタ間のXCHGはμOPSが3つに分解される
とあるから(PentiumIII系)計算が合いますね。
PentiumWはALUが倍速になっているものの、ポートの数が減って
いるため、事情は異なるかと思いますが。

323 :vc,bcc,dmc,gcc2.95 で確認:03/02/06 02:54
void putbar(int n)
{
int k;
for( k=0; k<n; ++k )
putchar( "****|"[k%5] );
putchar('\n');
}

324 :デフォルトの名無しさん:03/02/06 03:45
「読みにくい」 と 「トリッキー」 を勘違いすることなかれ

325 :デフォルトの名無しさん:03/02/07 01:50
putbar()って何?
"****|"の文字の並びに何か意味があるの?

326 :デフォルトの名無しさん:03/02/07 08:34
putbar(13)
****|****|***

というように5文字ごとに|を入れたいってことだろう。

327 :デフォルトの名無しさん:03/02/07 10:19
putchar((k % 5)["****|"]);

328 :デフォルトの名無しさん:03/02/13 16:55
ほしゅ〜

329 :デフォルトの名無しさん:03/02/13 17:17
>>311
RODE 社の非常に優秀な製品です。
http://www.rodemic.com/specsnt2/


330 :デフォルトの名無しさん:03/02/18 02:41
VBだけど

Dim buf As String * 260
hoge=Left$(buf, GetWindowsDirectory(buf, 260))

331 :デフォルトの名無しさん:03/02/18 09:52
>>330
どこがトリッキーなのかわからん。解説希望。

332 :デフォルトの名無しさん:03/02/18 10:19
ぬるっぽーなコードきぼん

333 :872:03/02/18 10:21
>>331
bufの値が空白に見えるうちにLeft関数に渡すところじゃない?
ついでにGetWindowsDirectoryが取得した文字数を返すから不要なスペースを除去できる。
(ディレクトリ名に2バイト文字が入ると破綻しそうな気もするけど)

334 :デフォルトの名無しさん:03/02/18 10:55
Cだとごく普通のコードだな。

335 :デフォルトの名無しさん:03/02/18 11:50
昔BASICでよく使った手法思い出した。
RIGHT$("00"+HEX$(n),2)

Cのsprintf(s,"%02X",n)相当。

336 :デフォルトの名無しさん:03/02/18 12:31
>>335
RIGHT$(HEX$(256+n),2)

こっちが少しだけトリッキーかも 速度も速いし

337 :BASICうろおぼえ:03/02/18 20:48
どーせなら足し算じゃなく論理和で
RIGHT$(HEX$(256 OR n),2)

338 :デフォルトの名無しさん:03/03/01 00:27
http://www.emit.jp/prog/prog.html
のところに、4byteまとめて平均値を出す方法が
> unsigned long v0, v1, v2;
> // v0, v1 にはキャストするなり、あらかじめデータを入れておく
> v2 = (v0 & v1) + (((v0 ^ v1) & 0xfefefefe) >> 1);
のようにのっているんだけど…

どうしてこうなるの?
がんばっても理解できないので
解説してほしいのですが…

339 :デフォルトの名無しさん:03/03/01 01:12
加算をbit単位で考えてみれば自ずと理解出来るかと

340 :338:03/03/01 01:29
>>339
最初の v0 & v1 は、足したらケタがあがるところで、
次の v0 ^ v1 は、足すところで、
次の & と >> は半分にするところでしょうか?

なんで
( ((v0 & v1) + (v0 ^ v1)) & 0xfefefefe ) >> 1
ではないの?

341 :デフォルトの名無しさん:03/03/01 02:05
(v0 & v1) の方は1bit繰り上がりがあるから。

342 :338:03/03/02 01:35
なんとなくわかってきた気がします。
どうもありがとうございました。

343 :デフォルトの名無しさん:03/03/02 03:43
>>338
現在のCPUが、どうやって加減算をしてるか勉強すれば
一発で理解出来るようになるよ

344 :デフォルトの名無しさん:03/03/09 14:08
#define cat(a, b) a##b
#define rem       cat(/, /)

はがいしゅつですか?

345 :デフォルトの名無しさん:03/03/09 15:06
プリプロセスの結果としてできたコメントってプリプロセッサは削除するんだっけ?

346 :デフォルトの名無しさん:03/03/09 15:21
…らしいね。

347 :デフォルトの名無しさん:03/03/09 17:17
規格上求められる挙動なんだっけ、という意味でよろしこ。

348 :デフォルトの名無しさん:03/03/10 13:27
>>344
前スレの138にて。意味違う(?)けど。
ってこれ副作用あるね・・・

349 :デフォルトの名無しさん:03/03/10 13:28
あげちった(汗

350 :デフォルトの名無しさん:03/03/10 15:17
##って引数以外に効果あったっけ?

351 :デフォルトの名無しさん:03/03/10 15:22
ない。

352 : ◆pIiNuLLPo6 :03/03/27 17:45
期待あげ。2週間は痛い。

353 :デフォルトの名無しさん:03/03/28 12:21
8085のdiv関数のコード逆アセンブル:
CDxxxx call  DIVIHD##;HL/DE-->DE=余り、HL=商
;   除算を実行した直後は上位ワード=余り,下位ワード=商、が標準的手法。
C1   pop   B     ;リターンアドレス pop
F1 pop   PSW
F1   pop   PSW    ;SPを返却値のアドレスまでpop
D5   push  D     ;余りpush
E5   push  H     ;商をpush
C5   push  B     ;リターンアドレスpushでcall時点の状態
C9   ret        ;リターンアドレスpop, 分岐
;   1バイト命令だけでよく書けてると思います。んで、この結果を
sprintf(wk,"・・・%d %d",div(int,10)で0.1単位の整数の編集に使い、
割り算を1回ですませた。3MのCPUでシビアな処理の所、ウマーでした。


354 :デフォルトの名無しさん:03/03/28 13:43
>>353
シビアな処理でsprintfってあんた、、、
目の付け処がピンボケです。

355 :デフォルトの名無しさん:03/03/28 23:42
#define QUESTION(bb) ((bb)||!(bb)) /* hamlet, shakespeare */

356 :デフォルトの名無しさん:03/03/28 23:49
トリッキーではないがなw

357 :355:03/03/29 00:09
気に入ったんで・・・汗
昔みたいに盛り上がらないかなぁ。

358 :デフォルトの名無しさん:03/03/29 11:21
もう2周年超えたんだなsage

359 :353:03/03/29 21:24
>>354 そんなにピンボケでもなかったのですよ。printfルールの文字列を
出力する仕事だったので、ASMで変に固定長の出力とかは不自然に見える。
10で割った商と余りを編集するのに、353のやり方を使わないと/で除算、
%でまた除算てことになるのですね。だからこれは当たりと思った手法です。
私もASMで商と余りを使う手法を考えたら結局これに行ったのです。

360 :デフォルトの名無しさん:03/03/29 21:59
>>359
printfのコストを考えれば2度の割り算なんてないのと同じということだとおもわれ。
割り算1つ減らすよりもほかに最適化する方法はありそうだしな。

361 :デフォルトの名無しさん:03/03/30 04:28
つーかね。
定数 10 による除算は、勝手に最適化されるぞ。

362 :デフォルトの名無しさん:03/04/01 06:11
353の例では(LSI i8080 CG ver 3.4a Copyright (C) 1986-1994)
最適化はされませんでしたね。いちいちどんなASMコードが出るか見ながら
c表現を手動最適化でした。sprintf系も「実数ハンドリング機能を省いた
コンパクト版」というのが付いていてデフォールトはそちらを使うように
なってました。

363 :デフォルトの名無しさん:03/04/01 09:36
>>353=362 は小手先の最適化で天狗になって全体を通しての
効率を見ることができないヤシってことでFA?

364 :デフォルトの名無しさん:03/04/01 09:56
>>362
それは最適化コンパイラなのか?

365 : ◆S2HEROnM/c :03/04/02 01:33
>>261
余ってるショップ行けばタダでもらえる

366 :デフォルトの名無しさん:03/04/02 01:57
>>365
何をだよ…

367 :362:03/04/02 06:57
>>364 最適化なしコンパイラ。せいぜい前の命令で使ったレジスタ値を次で使う程度。
>>363 んじゃ全体を通しての効率の噺ね。ROM32K,RAM8K,3Mの8085A,8251が4CH
皆4.8K,8,1,N。1,2CHからバイナリ13バイトで位置・速度・移動方向等の情報が最大
60個ブロッキングされて3秒毎に送られてくる。それを3,4CHにASCII文字列にして
送信する。1個を編集した文字列は55バイト前後になる。旧systemはASM5K行位
あったが、有効レコードが30個あたりから出力が止まるから何とかしてくれと
いう問題でした。

368 :362:03/04/02 07:16
ROMは余ってますが通信条件から、有効レコード28個あたりで出力時間が3秒になる
のが判りますね。そのときもう次の入力が入って来るわけで、この事態に対し
旧systemは脆弱だったわけです。もともと6秒間隔で作って、後から勝手に
3秒間隔で使い始めたので、作った奴にバグだ直せと言えなかったようです。
実装RAM条件から、60個出力が2度続くように耐えられるだけ送信リングバッファ
を確保できないことが判ります。皆さんならどう解決しますか?
あ、割り算の話は、バイナリ値が0.1単位の整数表現だからです。

369 :デフォルトの名無しさん:03/04/02 09:08
>>362
もういいよ。この話題あきたよ。読みにくいし。

370 :デフォルトの名無しさん:03/04/03 11:20
lsr #5,d0
btst d0,#$90

Shift_JIS の1バイト目判別。
(0x80 とか 0xfd 以降にも機種依存文字が割り当てられてた環境だった)

371 :デフォルトの名無しさん:03/04/03 11:55
>>370
何のアセンブラだか分からんので、Cで書いてくれない?

372 :デフォルトの名無しさん:03/04/03 22:45
>>371
cはunsigned char
(1<<(c>>5))&0x90

しかしこのコードの一番のポイントはbtst命令のオペランドなのだが…

373 :デフォルトの名無しさん:03/04/04 10:23
>>372
「何のアセンブラだか分からん」 と言う人に、「ポイントはbtst命令」 と返すのは
いかがなものかと。

374 :デフォルトの名無しさん:03/04/04 16:02
>>370
> (0x80 とか 0xfd 以降にも機種依存文字が割り当てられてた環境だった)
理由が苦しいな、、、

といいつつ、同じく0x80,0xFC-を無視していいときは
0xE0とtesttして、サインフラグとパリティ Oddを見てたよ。

結局のところ>>370と発想は同じかもしれん。

375 :デフォルトの名無しさん:03/04/06 02:48
>>373
ごめん、、、でもうまく説明できない・・・

376 :デフォルトの名無しさん:03/04/09 21:13
保守

377 :デフォルトの名無しさん:03/04/15 23:05
最近HTTPリクエストが面白くて色々遊んでいるんだけれど、ちょっとお題を。
HTTP リクエストとブラウザ上の JavaScript のみを使って、
なにか適当な2つのブラウザ同士が通信する事って出来るかな?

俺の結論は「出来ない」なんだけれど…。
どうあがいてもブラウザで Listen 出来ないよね?
間に中継サーバを立てればもちろん出来るとは思うけど、どうでしょう?

378 :デフォルトの名無しさん:03/04/16 01:17
>>377
ブラウザが JavaScript で Listen 出来ちゃったら
そのコード埋め込んであるページを開いた時点で・・・(((;゚Д゚))ガクガクブルブル

379 :デフォルトの名無しさん:03/04/16 23:49
中継サーバを立てたら、すべてのデータが全部中継サーバ経由になるのかな?

380 :デフォルトの名無しさん:03/04/16 23:52
>>377
Javaアプレット経由でできるかも。
通信用のアプレットを作って、staticな変数とかでやりとり...
ちょっとトリッキーだな。

381 :デフォルトの名無しさん:03/04/17 00:41
>>380
具体的にアプレットを使ってどうやるんだ?
中継サーバなしでは無理だろう、たぶん。

中継サーバの負荷をどれだけ小さくできるか、という方がトリッキーっぽい

382 :山崎渉:03/04/17 15:15
(^^)

383 :デフォルトの名無しさん:03/04/17 17:06
HTTPを使ったP2P…不可能ぽ
間のサーバがあったところで、転送量を分散するシステムが必須だな

384 :デフォルトの名無しさん:03/04/19 22:58
>>377
IEだったらセキュリティーホール突けば…

385 :山崎渉:03/04/20 03:15
   ∧_∧
  (  ^^ )< ぬるぽ(^^)

386 :山崎渉:03/04/20 03:48
   ∧_∧
  (  ^^ )< ぬるぽ(^^)

387 :デフォルトの名無しさん:03/04/20 11:26
>>384
思いつきで言うな

388 :デフォルトの名無しさん:03/05/04 12:49
これはトリッキーかなぁ…。(ーー;)
かなり前作った矩形同士の当たり判定ルーチン。(VisualC)
[ ]が付いたり付かなかったりしてて気持ち悪い。(苦笑)

  __asm{

    mov eax, left2;
    mov edi, top2;
    sub eax, [left1];
    sub edi, [top1];
    mov esi, [right1];
    mov edx, [bottom1];
    sub esi, right2;
    sub edx, bottom2;
    or eax, edi;
    or esi, edx;
    xor ebx, ebx;
    or eax, esi;
    setge bl;


389 :388続き:03/05/04 12:49
    mov eax, [left1];
    shl ebx, 1;
    mov edi, left2;
    sub eax, right2;
    sub edi, [right1];
    mov esi, [top1];
    mov edx, top2;
    sub esi, bottom2;
    sub edx, [bottom1];
    and edi, eax;
    and esi, edx;
    xor eax, eax;
    xor ecx, ecx;
    sub eax, ebx;
    and edi, esi;
    sets cl;

    sub eax, ecx;

  }

390 :388:03/05/04 13:13
!(゜∀゜;
なんか前スレに似たようなものが…!?(ガーソ!)

よく見ておけばこんなクソコードを晒すこともなかったのにィ!(笑)

391 :デフォルトの名無しさん:03/05/04 18:35
前スレの15がウザイ

392 :デフォルトの名無しさん:03/05/23 17:06
誰かこれを解説してくれ。

/* invariant in modulo 1<<31 */
#define EXTEND32(x) (((1<<31)-1-(x))^~(~0<<31))


393 :文系中退 :03/05/24 14:45
>>392
未定義。intが32ビットで2の補数表現のマシンでも動く保証はない。

394 :デフォルトの名無しさん:03/05/25 01:24
どこが未定義?

395 :デフォルトの名無しさん:03/05/25 05:53
ここ。 (1 << 31) - 1

396 :デフォルトの名無しさん:03/05/25 08:14
その後の~(~0<<31)は大丈夫なの?

397 :デフォルトの名無しさん:03/05/25 08:50
>>396
intが32ビット以上なら大丈夫。

398 :デフォルトの名無しさん:03/05/26 09:20
>>392はintが32ビットよりも大きい場合のコードのようなんだけど、
それでも未定義?

つーか、このコードが意図してること分かる?

399 :山崎渉:03/05/28 13:08
     ∧_∧
ピュ.ー (  ^^ ) <これからも僕を応援して下さいね(^^)。
  =〔~∪ ̄ ̄〕
  = ◎――◎                      山崎渉

400 :デフォルトの名無しさん:03/06/12 23:39
400!

401 :デフォルトの名無しさん:03/06/19 19:19
>400
もう2週間くらい粘ってほしかった

402 :デフォルトの名無しさん:03/06/29 23:38
漏れも周波数は関係ないと思うが、OS は存分に関係ある気がする。

403 :デフォルトの名無しさん:03/07/11 03:05
(i==j==i) /* i=j=1 なら真 */
(i!=j==i) /* i=j=0 なら真 */

404 :403:03/07/11 03:15
ミスポ
(i==j==i) /* i=j=1 なら真 */
(i==j==!i) /* i=j=0 なら真 */

405 :403:03/07/11 03:18
あぁ〜
(i==j==!i) /* i=j=0 なら真 */
も、ダメぽ…
誰か考えてぽ

406 :デフォルトの名無しさん:03/07/11 03:28
(i==j==i) /* i=j=1 なら真 */
も、ダメぽ…
ダメダメぽ…
首吊ってくるぽ…

407 :デフォルトの名無しさん:03/07/11 04:52
後者なら

( !( i | j )) /* i=j=0なら真 */

とかは?前者はいまいち出てこないな。

408 :デフォルトの名無しさん:03/07/11 06:01
>>407
ちょっと変形すりゃできないか?
!((i-1)|(j-1))

409 :デフォルトの名無しさん:03/07/12 22:22
固定小数点の実装の仕方を教えてください。
解説しているサイトがあったらそれでもいいです。
環境はWindows2kです。
処理系はmingwでもvcでもC系ならなんでもいいです。
ちなみに32bitの固定小数点とfloat型は、
一般的にどっちが速いんでしょうか?

410 :デフォルトの名無しさん:03/07/12 22:26
精度はそんなに必要ないです。

411 :デフォルトの名無しさん:03/07/12 23:10
>>409
今時のCPUなら下手するとfloatのほうが速かったりするが

412 :デフォルトの名無しさん:03/07/12 23:46
もまいらHacker's Delight読め。

413 :デフォルトの名無しさん:03/07/13 01:43
>>409
src と dst が int なら最後に変換がない分固定小数点の方が速い
src と dst が float なら最後に変換がない分浮動小数点の方が速い
それくらい速度差って余りないよね。
ただ、掛け算、割り算が shift や lea に置き換え出来たりするとまた話が違ったり。
つーか、スレ違いだ。

414 :デフォルトの名無しさん:03/07/13 01:46
ありがとうございました。
そうですね、スレ違いっぽいと自分でも思ってました。
(固定少数点はトリッキーぽいかなと思ったけど)
とりあえずfloatで満足する速度が出るか試してから
また考えます。

415 :デフォルトの名無しさん:03/07/13 01:49
typedef float static_real;
#define STATIC_REAL_VAR(var)   (var)

C++なら演算子のオーバーライドとかできるから固定少数点にした方がいいとおもったのを
それにしておいて、不満があったら作るのも手。


416 :デフォルトの名無しさん:03/07/13 03:53
ひとりよがりということなら、C言語に於いて
foo.h:
typedef struct foo *FooP;
void
foo_afo(FooP p, 略);

foo.c:
struct foo {
 略
};
void
foo_afo(FooP p, 略) {
}

メンバ変数の情報隠蔽のみだが、一部の同僚には非常に不評であった。

417 :デフォルトの名無しさん:03/07/13 03:54
戻り値の型のあとで改行する人は大嫌いです。

418 :デフォルトの名無しさん:03/07/13 03:57
こんなのあった。


char *p = NULL;

printf("p = %s\n", p ?: "<NULL>");

419 :デフォルトの名無しさん:03/07/13 04:01
>>418
printf("p = %s\n", p ?p: "<NULL>"); の間違いか?

420 :デフォルトの名無しさん:03/07/13 04:02
☆貴方の見たい娘がいっぱいです☆
http://endou.kir.jp/yuminet/link.html

421 :デフォルトの名無しさん:03/07/13 04:07
>>419
ぶー、C言語的には間違えていません。
結構知られてないのね。

422 :デフォルトの名無しさん:03/07/13 04:09
オペランド省略できるんだ?

423 :デフォルトの名無しさん:03/07/13 04:10
>>422
Perl / Java だと出来ないみたい…
C言語ってトリッキーだねえ


424 :デフォルトの名無しさん:03/07/13 04:12
>>421
ANSI Cでは許さないとgccが言ってきたぞ。警告ではあるが。

425 :デフォルトの名無しさん:03/07/13 04:23
gccがぶーたれるなら規格外なんだろうなあ。
調べるのが面倒臭くなった…。

426 :デフォルトの名無しさん:03/07/13 04:24
-ansi -pedantic
ここまでやらないと言ってこないけどね。

427 :デフォルトの名無しさん:03/07/13 10:22
トリッキーかは知らんが
int A;//Aは任意の数
A%4; は
A&3; に等しい。
以外に知らない奴多いが「割る数」が2^n(n=整数)なら
2^n-1で&したのと同じになる。
50倍ほど速くなったから、知っとけ。

428 :デフォルトの名無しさん:03/07/13 11:01
>>427
それって基本中のキホンだぞ。
ホンキで知らないヤシが多いなんて思ってるのか?


429 :デフォルトの名無しさん:03/07/13 11:05
>>427
それくらい最近のコンパイラなら最適化でやってくれると思うけど。

430 :_:03/07/13 11:05
http://homepage.mac.com/hiroyuki44/hankaku09.html

431 :デフォルトの名無しさん:03/07/13 11:23
前どっかのスレで書いたコード
多分どんな型でもOKなSwapマクロ

#include <stdio.h>

#define Swap(a,b) \
{\
char static_assert[sizeof(a)==sizeof(b)];\
typedef struct { char buf[sizeof(a)]; } temp;\
temp t=*(temp *)&a;\
a=b;\
*(temp *)&b=t;\
}

int main(){
int a=0,b=1;
Swap(a,b);
printf("a=%d,b=%d\n",a,b);
}


432 :デフォルトの名無しさん:03/07/13 11:26
>>431
構造体を作るよりも配列にmemcpyした方がいいと思うけど

433 :デフォルトの名無しさん:03/07/13 12:29
>>428
うち、某大手ゲーム会社だけど、メインプログラマでも
それ知らない奴いるんだよね・・・・

まあ、そいつはメインとは言っても、他のチームのコピペ改造だけで
作ってる奴だけど。

434 :_:03/07/13 12:35
http://homepage.mac.com/hiroyuki44/hankaku09.html

435 :デフォルトの名無しさん:03/07/13 12:40
>>433
うーん、それはちょっといただけないNa-。

436 :デフォルトの名無しさん:03/07/13 13:05
>431

C++ならテンプレートで済む話だね。
昔はsizeof()使うマクロとかよくやったけど。

437 :デフォルトの名無しさん:03/07/13 13:05
俺も某ゲーム会社でプログラマしてます。
&は使わずいつも%を使ってます。

ですが変数の型はちゃんとunsignedにしてますから
最適化により同等のコードが生成されているはずです。

だから俺のコードで&使えるところで%使っている場合でも見下さないで下さい。
可読性とかを優先しているだけです。

438 :デフォルトの名無しさん:03/07/13 13:08
>>437
ゲームプログラマーは見下します。

439 :デフォルトの名無しさん:03/07/13 13:11
そうか、% か…

440 :デフォルトの名無しさん:03/07/13 13:18
>可読性とかを優先しているだけです。

スレ違い

441 :デフォルトの名無しさん:03/07/13 13:35
>>437
どんなコードがよく最適化されるかを精査した上で書くと
見た目素直なコードばっかりになるね。

442 :デフォルトの名無しさん:03/07/13 13:38
>>431
揚げ足取りだが
Swap(a, b);
最後のセミコロンはいらん

443 :デフォルトの名無しさん:03/07/13 13:45
MFCでCArray使ってて、配列要素から要素番号を得る方法が
ないと言われて作ってあげた関数だが↓

int CLine::GetIndex(CDoc *doc)
{
int iRet = int(this - doc->m_lines.GetData());

return iRet;
}

・・・別にトリッキーじゃないよな。「thisからCArray.GetData()を
引けばいいだけじゃん」と何度教えても、VBメインの香具師には
伝わらないかと思った。

444 :デフォルトの名無しさん:03/07/13 13:53
>>443
結局人によるのかなー

445 :デフォルトの名無しさん:03/07/13 14:05
>>443
そういう式も「ポインタの概念の理解」の範疇なのかな・・
ひっかかる人は大変そうだ。

ところで、そこではintへキャスト(というか明示的型変換)する必要ないよね。
ただ引くだけで結果型はintだし。
(キャストは書き間違えるとつらいので)

446 :デフォルトの名無しさん:03/07/13 14:21
ptrdiff_t

447 :デフォルトの名無しさん:03/07/13 14:23
確かに

448 :443:03/07/13 16:35
漏れも、何でキャストしたんだろうと思ってやってみたよ。VC7だと、

typedef _W64 int ptrdiff_t;

なんでワーニングが出るんだ。

449 :デフォルトの名無しさん:03/07/13 16:38
>>448
ああ、Win64版コンパイラを使うときは問題が起こるぞっていう予告警告か。

450 :デフォルトの名無しさん:03/07/13 16:46
予告犯罪みたいだな

451 :427:03/07/13 18:08
>>429
遅レスだが、
Borland C++ Compilerは、
%4のアセンブラコードを出すよ。
あと、マジで知らん奴はいるから。

452 :デフォルトの名無しさん:03/07/13 19:03
偶数・奇数の判定も%2より&1のほうが速い?

453 :デフォルトの名無しさん:03/07/13 19:06
最適化のされかた具合によりますが、
% は副産物として商も求められているかも…です。

454 :デフォルトの名無しさん:03/07/13 19:10
符号付きかどうかでも変わる気がする

455 :デフォルトの名無しさん:03/07/13 19:14
ん?そういや負の値の余りってどうなるんだ?
-5 % 3 とか
9 % -7 とか


456 :デフォルトの名無しさん:03/07/13 19:19
正負混合のときは符号は処理系依存だったと思う。
C99では決まってるんだっけか。

457 :デフォルトの名無しさん:03/07/13 19:39
そんなときのためにdiv関数があるらしい。(Cスレより)

458 :デフォルトの名無しさん:03/07/13 19:45
>>451
最適化レベルをあげても?
もしそうならそのコンパイラをつくった人たちも「それ」を知らなかったりして。

459 :デフォルトの名無しさん:03/07/13 19:55
は?

460 :デフォルトの名無しさん:03/07/13 20:28
>>451
unsignedならちゃんと最適化したと思ったが。
>>431
{}で囲むよりdo {} while(0)が良いかも。

461 :デフォルトの名無しさん:03/07/13 21:21
if(flag)
 MACRO;
else
 MACRO2;

MACROの後ろの ; 対策ですね。

462 :デフォルトの名無しさん:03/07/13 23:45
>>431
char static_assert[...];
より
typedef char static_assert[...];
の方が良い。

463 :431:03/07/14 00:00
皆さんの意見を総合。C++大すきっコなので使うことは無いですが。

#include <memory.h>
#define Swap(a,b) \
do{\
typedef char static_assert[sizeof(a)==sizeof(b)];\
char temp[sizeof(a)];\
memcpy(temp,&a,sizeof(a));\
memcpy(&a,&b,sizeof(a));\
memcpy(&b,temp,sizeof(a));\
}while(0)


464 :デフォルトの名無しさん:03/07/14 00:35
memcpyはstring.h

465 :デフォルトの名無しさん:03/07/14 00:37
>>462
型定義なら実際に領域が取られることはない。ということか。考えたなぁ。

466 :名無し:03/07/14 00:39
>>464
memory.hにもあったような

467 :デフォルトの名無しさん:03/07/14 01:07
オリジナルと比べると、aとbの型が違っててもサイズが同じなら動くように
改良されてる?

468 :デフォルトの名無しさん:03/07/14 01:12
>>467
改良というより仕様変更だな。

469 :デフォルトの名無しさん:03/07/14 14:00
>>431
そのstatic_assertの使い方は_AC_COMPUTE_INTのに似てるな。
あっちは[1-2*(sizeof(a)!=sizeof(b))]で負になるようにしてるけど。

470 :デフォルトの名無しさん:03/07/14 16:58
switch(0)
{
case 0:;
case sizeof(a)==sizeof(b):;
}

メリットなし。

471 :431:03/07/14 20:09
>>469
static_assertはmodern c++ designに書いてあったのをパクッた。

472 :山崎 渉:03/07/15 09:49

 __∧_∧_
 |(  ^^ )| <寝るぽ(^^)
 |\⌒⌒⌒\
 \ |⌒⌒⌒~|         山崎渉
   ~ ̄ ̄ ̄ ̄

473 :デフォルトの名無しさん:03/07/15 17:03
template <bool>struct static_assert;
template <>static_assert<true>{};
#define STATIC_ASSERT(expr) typedef static_assert<( expr )> static_assert_tmp##__LINE__;

BOOSTのヘッダー見たところ、こんな感じだった気がする


474 :431:03/07/15 20:29
>>473
C++版はそう。俺が書いたのはC版。

475 :デフォルトの名無しさん:03/07/16 05:54
#define STATIC_ASSERT(expr) typedef struct {\
char dummy[(expr)?1:-1];\
} static_asserttmp##__LINE__;
#define STATIC_ASSERT2(expr) typedef struct static_asserttmp_2_##LINE__ {\
char dummy[(expr)?1:-1];\
} static_asserttmp##__LINE__;

単体で使えるC版を考えるとこうかな
追記:1行で2つ使うと悲惨なことになるかも。
プリプロセッサ内部で使う場合は要注意


476 :デフォルトの名無しさん:03/07/18 16:42
int c = 1/(sizeof(a)==sizeof(b));

零除(ry

477 :デフォルトの名無しさん:03/07/18 19:04
>>476
それってエラーになるって決まってるんだっけ?

478 :デフォルトの名無しさん:03/07/24 20:04
保守

479 :デフォルトの名無しさん:03/07/28 23:36
簡単な言語系作ってる時に、式の評価でこんなコード書いてみたんだけどどでしょ?
while(((op=C_ADD,opl=6,len=1,*p=='+') ||
(op=C_SUB,opl=6,len=1,*p=='-') ||
(op=C_MUL,opl=7,len=1,*p=='*') ||
(op=C_DIV,opl=7,len=1,*p=='/') ||
(op=C_MOD,opl=7,len=1,*p=='%') ||
(op=C_FUNC,opl=8,len=1,*p=='(') ||
(op=C_LAND,opl=1,len=2,*p=='&' && p[1]=='&') ||
(op=C_AND,opl=5,len=1,*p=='&') ||
(op=C_LOR,opl=0,len=2,*p=='|' && p[1]=='|') ||
(op=C_OR,opl=4,len=1,*p=='|') ||
(op=C_XOR,opl=3,len=1,*p=='^') ||
(op=C_EQ,opl=2,len=2,*p=='=' && p[1]=='=') ||
(op=C_NE,opl=2,len=2,*p=='!' && p[1]=='=') ||
(op=C_GE,opl=2,len=2,*p=='>' && p[1]=='=') ||
(op=C_GT,opl=2,len=1,*p=='>') ||
(op=C_LE,opl=2,len=2,*p=='<' && p[1]=='=') ||
(op=C_LT,opl=2,len=1,*p=='<')) && opl>limit){
// 演算子がある間継続
}


480 :デフォルトの名無しさん:03/07/29 03:02
>>479
どうせならこう書くな。
while((*p=='+') ? (op=C_ADD,opl=6,len=1) :
      (*p=='-') ? (op=C_SUB,opl=6,len=1) :


481 :デフォルトの名無しさん:03/07/29 23:56
トリッキーではないな。ちょい読みにくいし、実行速度の面で無駄が多い。
じゃあどういうコードが良いんだろう、と言われると迷うな。考えてみよう

482 :デフォルトの名無しさん:03/07/30 13:17
whileでトリッキー??にする理由が分からない。
とりあえず毎回op, opl. lenに代入する必要はないから
480に一票。

デバッグ楽にするために俺なら*pのswich文かな。
全くトリッキーではなくなるが、タイプミスが減る。w

483 :デフォルトの名無しさん:03/07/30 19:55
>>481
> 実行速度の面で無駄が多い。
479も480も最適化される可能性が他界

484 :デフォルトの名無しさん:03/07/30 21:04
(op=C_ADD,opl=6,len=1,*p=='+')
は、*p=='+'の結果によらず、
op=C_ADD,opl=6,len=1が実行されるよね?
だったら、>>479>>480が同じような最適化されるとは思えないなぁ
って、試せよ>>ワシ

485 :デフォルトの名無しさん:03/07/31 00:49
でもその後で上書きされるなら、省略される可能性もある。
逆に、>>480のコードが再配置されて>>479みたいになることもある。

486 :デフォルトの名無しさん:03/07/31 02:13
>> 逆に、>>480のコードが再配置されて>>479みたいになることもある。

書いてない処理、コンパイラが足す訳ないじゃん。あほか。

487 :デフォルトの名無しさん:03/07/31 02:24
はぁ?

488 :デフォルトの名無しさん:03/07/31 05:40
>>486は放っておくとして、
*p=='+'が
真なら上書き
偽ならそのまま
代入が1回は行われるから、同じにはならんが近いのは
出してくれるかもしれん

でも、最適化を期待して、読みにくいコードを書くのはどうかと。
普通、最適化を期待して、読みやすいコードを書くものではないかと。

489 :480==485:03/07/31 07:59
>>488
> でも、最適化を期待して、読みにくいコードを書くのはどうかと。
ではなくて、「結果的に>>479的になることもある」といってるだけ。


490 :486:03/07/31 10:12
明らかに479より480の方がステップが少ないので、
479が最適化されて480になることはあっても
逆はないだろと言いたかった。

479は変数代入後に*pを評価しろとコンパイラに
指示している。480は*pを評価してから代入だろ。

「書いてない処理」とは評価前の代入のことだ。

488も同じ話をしていると思うが.

491 :デフォルトの名無しさん:03/07/31 10:29
そもそも479は、「,」演算子で区切られた式は左から順に評価されることが保証されている、というC++の仕様を知っているのか?

492 :デフォルトの名無しさん:03/07/31 16:32
>>490
一度アセンブラコード読んでみろ。

493 :デフォルトの名無しさん:03/07/31 21:48
>>492
藻前が読め

494 :490 != 493:03/08/01 01:26
アホは言い過ぎた。夜中だし酔ってたんでな、謝るよ。

漏れは479でも480でもないが、480の方が速いだろうと思う。
その点は譲りたくないな。w

スマンカッタ

495 :デフォルトの名無しさん:03/08/01 02:10
藻前、案外いい香具師だな

496 :山崎 渉:03/08/02 02:39
(^^)

497 :デフォルトの名無しさん:03/08/02 13:35
480が479より速いことはあっても、479が480より速くなることはないのはいいよね?

498 :デフォルトの名無しさん:03/08/02 16:42
コンパイラ次第だってば。まぁ479が480と同じになるくらいならともかく、
より速くなることはたしかに考えにくいがな。


499 :デフォルトの名無しさん:03/08/05 19:59
最小のwindowsプログラム(ただし窓を表示)って何byteになるだろ?
356テトリススレで話題になってたので気になった。

500 :デフォルトの名無しさん:03/08/05 20:10
窓表示させるだけなら…

501 :デフォルトの名無しさん:03/08/05 20:32
何気にあのスレ木になっちゃうんだよね。7行とか制約があるの大好き(藁

502 :デフォルトの名無しさん:03/08/05 20:58
COMファイルで実装なんて出来ないよな?
exeファイルならシンボル解決だけで辛そう。
ExitProcess、という文字列だけで10byteだし

503 :もしかすると最小(12byte):03/08/06 00:32
エディタで↓と書いて拡張子vbsで保存。

WScript.Echo

504 :デフォルトの名無しさん:03/08/06 00:42
俺このスレ好きだなぁ。いつ来ても新しい話題が盛り上がってるし

>>503
それは却下でそ(笑)。多分MessageBoxも却下だと思われ。
ウィンドウプロシージャを呼び出すのを前提にするといいかもね。

ところで、このスレでこのOS依存の話題を続けてもいいのかなぁ?

505 :デフォルトの名無しさん:03/08/12 01:21
いぜん漏れがフロー読み違えたコード。正常時および異常時のループの回数を考えてくれ:

fRet = FALSE;
while(1) {

// 中略

if (GetAttribute(pNode, FROMY, strFromY) == FALSE){
TRACE("Not found %s Attr\r\n", FROMY);
strFromY = "0";
break;
}


if (GetAttribute(pNode, TOY, strToY) == FALSE){
TRACE("Not found %s Attr\r\n", TOY);
strToY = "0";
break;
}

fRet = TRUE;
break;
}

何がトリッキーかというと、この香具師の組織では「複数return禁止」「goto禁止」だったんだ。
だからってこれならいいのかと小一時間・・・

「頼むからgoto使ってくれ」と言いたくなったよ。

506 :デフォルトの名無しさん:03/08/12 03:30
>>505
複数リターンは下手するとメモリリークの原因にもなりかねんから
なるべく使わないようにしてるけど。

while(1) { break; } や do { } while (0);
もいいか悪いかは別としてgotoの代わりとしては
よく使われてるんじゃないの?


507 :デフォルトの名無しさん:03/08/12 10:53
>>505
すまん、あおりではなく素でどこが問題なのかわからないんだけど

508 :デフォルトの名無しさん:03/08/12 11:00
while(1)よりはdo whilte(0)のほうが繰り返さないということが読み取り易いかな。
しかしgotoなんか使う場面とは思えんなあ。

一般的にgoto禁止でも普通ぜんぜん困らんが、複数returnはむしろリファクタリングで
積極的に使うべきものだから禁止ってのは辛いな。

509 :デフォルトの名無しさん:03/08/12 11:01
>>506
今時はスマートポインタなどで確実にデストラクタでガードするようにするので
複数returnは基本

510 :デフォルトの名無しさん:03/08/12 14:38
>>509
trueやfalseではなく1とFALSEを使っているところから、C++ではなくCだろうと思われ。

511 :デフォルトの名無しさん:03/08/12 21:02
ああ、やっとわかった。
これはそんなにトリッキーでは無いんじゃないかな?

一般的なスタイルなら、do...while(0) だから、そちらの方が読みやすいけど。

512 :505:03/08/12 22:47
元コードは、CライクなC++です。COMというかMSXML関係。

漏れはループでないシーケンシャルな処理には「決して」while/do/forは使わん
主義なのだが(言ってることおかしいか?)、どうやら世間ではそうでもないのかな?
特に、whileブロックの最終行にbreak;は生涯で一度も書いたことが無い。

少しは自分の社会勉強になったかな。w

513 :デフォルトの名無しさん:03/08/12 23:19
いや、「決して」というのを除けば多数派だと思う。

514 :505:03/08/12 23:34
このアプリの他の部分は、いかにも教科書通りなMFC-WIN32アプリなんだが、GDI関係とかも
最新のスタイルならきれいにスマートポインタで開放・復旧できるもんなのかな?

漏れの知識は少し古いので分からん。ので、古典的だがgotoでexitラベルに飛ばして、そこで
finally()処理をしてからreturnというルールにした(かった)。


515 :505:03/08/12 23:52
もちろん do { } while (0); と書かれていれば、この場合は何も理解困難なことはなかった。

516 :デフォルトの名無しさん:03/08/13 00:13
要は自分の考え方と違うソースが読めないんだろ?

517 :通りすがり:03/08/13 00:37
漏れは同じ手に引っかかった事があるから、>>505の気持ちはわかる。
goto使えとは思わんかったけど、do{}while(0); 使えよとは思った。

…更にその後 do{}while(0); は使うなと言われて唖然。

518 :505:03/08/13 00:59
>>516
漏れに文句いわれた香具師は、「goto、複数returnありの組織とは思わんかった」つっとった。
その時もだが、ここに書いてみて改めて勉強になったよ。w


519 :505:03/08/13 02:35
漏れのgoto擁護、落語だと思って聞いてくれ:

1) 「プログラミング言語C第二版」(K&R)には、
「(gotoの)最も一般的な使用は、深く入れ子になった構造での処理を中断させる場合である」
とある。

2) 「プログラミング言語C++第三版」(Stroustrup)には、
「gotoを使ってもよいまれなケースのひとつは、入れ子状のループ、switch文からの脱出である」
とある。

3) C/C++の子孫であるJavaおよびC#には、finally{}節が存在する。

・・・以上のことから漏れ個人は、C/C++においては、たとえループやswitch文がネストしていない
場合でも、goto finally;型の用法は良性と見ていたりする。

Java/C#との論理的互換性・移植性を考えても、その使い方は悪性ではない。というか、見かけ
上のgotoや複数returnを回避するためにループ構文を使うのはよくないんではないか、とか思う。

(gotoスレにいくべきだったかも知れんな)

520 :デフォルトの名無しさん:03/08/13 18:54
>>514
GDIだろうがなんだろうが出来るし、例外処理対策を考える場合
デストラクタでやる以外にない。

521 :デフォルトの名無しさん:03/08/15 15:39
505自身を貶すつもりはないが、今のプログラマは505程度のコードでつまってしまうレベルということはわかった。

522 :山崎 渉:03/08/15 17:18
    (⌒V⌒)
   │ ^ ^ │<これからも僕を応援して下さいね(^^)。
  ⊂|    |つ
   (_)(_)                      山崎パン

523 :デフォルトの名無しさん:03/08/16 16:30
>>521
ケースバイケース。
漏れは↓のようなコードのデバッグで詰まったことがある。

・関数仕様:
 「ある条件」を満たすまで待つスレッド。

・症状:
 「ある条件」を満たすのを待たない

・実装:
DWORD hoge_thread()
{
  :
 while(1){
  int flg = hoge();  // 実際はこの中でループ。判定式が間違っていた。
  if( flg == ERROR_HOGE ){
   break;
  }
  break;  // ←バグだと思って消した
 }
  :
}

break のせいでループしないと思い込み、
消したら今度はフリーズしたもんで
小一時間考え込んでしまったよ…

524 :デフォルトの名無しさん:03/08/17 01:55
>>523
まあ始めてみたらそう思うだろうけど、
小一時間考え込むのはデバッグのセンス悪杉
がんばれ

525 :523:03/08/17 02:24
>>524
漏れのセンスが悪いと決め付けるんじゃなくて、
hogeの中身が小一時間悩むに相応しい内容だったとか、
"小一時間"に誇張が含まれてるとか、もっと想像力働かせて欲しい…

…などと書くと「コイツはダメな仕様書書く奴」とか言われそうだな。


526 :デフォルトの名無しさん:03/08/17 10:29
>>525
そういうのは織り込み済みで、センスが悪いんだろう(藁

527 :デフォルトの名無しさん:03/08/17 16:59
>>526
いい事いった

528 :デフォルトの名無しさん:03/08/17 17:43
DWORD hoge_thread()
{
  :
 while(1){
  int flg = hoge();  // 実際はこの中でループ。判定式が間違っていた。
  if( flg == ERROR_HOGE ){
   break;
  }
  break;  // ←バグだと思って消した
 }
  :
}

そもそもこんな関数作るやつのセンスが無いんだけどな


529 :505@休み明け:03/08/18 17:12
whileブロックの最後でbreak;やっぱあるんだな。w
引っかかる香具師も俺だけじゃないらしい。

トレースに費やした時間よりは、書いた香具師に
問いただした時間のほうが長かったよ。そいつが
別の仕事入ってたんで、同じ形式のコードを5箇所
位自分で改善しないといけないのが一番の苦痛だった。

530 :デフォルトの名無しさん:03/08/18 18:46
前スレで、
switch(...) {
    case LABEL_A: {
        ...
    } if(false)
    case LABEL_B: {
        ...
    } if(false)
    case LABEL_C: {
        ...
    }
    ...(共通処理)
}
というコードがあったけど、このコードはまず所見では理解されないだろうなぁ。
書きたくなる気持ちは非常によくわかってしまうが、インライン関数化すべきか。

531 :デフォルトの名無しさん:03/08/18 20:35
>>530
そういうときは共通処理を関数化するか、
switchをもう一段入れてる。gotoでまとめることもあるけど。
switch(X) {
case LABEL_A:
case LABEL_B:
case LABEL_C:
 switch(X) { // Xは上と同じ式
 case LABEL_A:
  ...
  break;
 case LABEL_B:
  ...
  break;
 case LABEL_C:
  ...
  break;
 }
 ...(共通処理)
 break;
....
}

532 :デフォルトの名無しさん:03/08/18 22:23
>>531
(あくまでも個人的にだが)美しくない気がする。自分では書きたくない。
530の方がトリッキーな分まだ美しいが可読性は著しく落ちるな。

しかし難しいよな。たとえば共通処理が2〜3行程度だった場合
わざわざインライン関数を書くのもなんだか美しくないし、
かといってcaseの中身を別々の関数にしようと考えてしまうと
2〜3行のcaseが10個くらいあった場合に悶え死にしそう。

どこかの組織で書く場合ならば、やっぱり531を選択せざるをえないけれど、
その場合でも可能であれば下のようにして書きたいな。
switch(...) {
  case LABEL_A: ...; break;
  case LABEL_B: ...; break;
  case LABEL_C: ...; break;
  ...
}
switch(...) {
  case LABEL_A:
  case LABEL_B:
  case LABEL_C:
    ...(共通処理)
    break;
}

自分がメンテナンスするコードなら喜び勇んで530と書くけどな

533 :デフォルトの名無しさん:03/08/19 01:07
漏れなら素直にこう書く。

 switch( X ) {
  case A: ...; break;
  case B: ...; X = A; break;
  case C: ...; X = A; break;
 }
 if( X==A ){
  (共通処理)
 }


534 :デフォルトの名無しさん:03/08/19 01:38
その後でXを使ったり、Xがconstだったりしたらどうする?
あまり素直ではないと思うぞ。それに532の方が読みやすい。

535 :532:03/08/19 02:34
Xがconstなら、そもそもswitchになんぞ入れない。
Xを再利用するならXのコピーを作る。
各処理を関数化するか否か迷う程度の大きさなら、
変数増やしてもさほど可読性は落ちないだろうし。

共通処理が1つでなく、組み合わせが多ければ>>534と書くけど、
switchは別々の関数に分ける。

536 :デフォルトの名無しさん:03/08/19 07:36
533が美しくないと思う論拠

・533はソースを読む人の意識からすれば、たとえばswitch文をあまり詳しく読まずに
下のif文まで読んでしまった場合に、そのif文が実行されるのがX==Aの場合だけだと
誤解される可能性が高い。532であれば、矛盾せずに読める。
・その後Xを用いた処理がある場合は変数をひとつ増やす必然性があるが、
ただ条件分岐のためだけにflag変数をひとつ増やしてしまうと、
同じ関数内で同じ意味の変数が出来ることになり、後のメンテナンスで問題を誘発しやすい
(間違えてXを使ってしまった、というバグが出ることは十分にありうる)

という意味で、533は美しくないと言える。
グループでのプログラミングの場合は可読性の低いプログラムを書くべきではないし、
自分さえわかればいいというのであれば530だな(笑)

537 :デフォルトの名無しさん:03/08/19 14:11
分かりやすさのために冗長さを我慢するなら、533のような中途半端でなく、
普通に531-532かな。言い方を変えれば533も「トリッキー」だろう。

前スレ読んでなかったんで、530は初めて見た。いろいろあるもんだな。

538 :デフォルトの名無しさん:03/08/19 14:18
昨日、

if (a == b == 0)
// something;

って書いちまってたよ。当然、

if ( (a == b) == FALSE)
// something;

と解釈されるよな。もうだめぽ現役引退か・・・


539 :デフォルトの名無しさん:03/08/19 14:57
bool型の暗黙型変換が許されない言語に乗り換えて生きろ

540 :デフォルトの名無しさん:03/08/19 15:02
>>535
constをswitchに入れることなど普通です
ex:
int function(const int mode) { switch(mode)...

541 :デフォルトの名無しさん:03/08/20 01:03
>>540
int型引数を const にする意味があるのかと小一時間。
参照なら分かりますが。

フラグを使う点や、ここがトリッキースレであることに目を瞑れば
↓が一番素直で簡潔だと思いますが。
フラグで可読性が落ちるほど大規模なら、素直に関数化すべきだし。
関数コールに比べりゃ、bool値の演算の方がコスト安いし。

 bool flg = true;
 switch( X ) {
  case A: ...; break;
  case B: ...; ; break;
  case C: ...; ; break;
  default:
   flg = false;
 }
 if( flg ){
  (共通処理)
 }

 (処理)
 if( flg ){    // 再度分岐が必要な場合に有利
  (共通処理)
 }

542 :デフォルトの名無しさん:03/08/20 12:39
>>541
フラグを使うと美しさが無いなぁ

543 :デフォルトの名無しさん:03/08/20 21:44
リファクタリングの本では、複数return回避のみが目的の fBreak 的フラグも
批判しているよね。

132 KB
■ このスレッドは過去ログ倉庫に格納されています

★スマホ版★ 掲示板に戻る 全部 前100 次100 最新50

read.cgi ver 05.04.00 2017/10/04 Walang Kapalit ★
FOX ★ DSO(Dynamic Shared Object)