x=x+1 по сравнению с x + =1

Проблема заключается в следующем условии

if($count > 1){
}

Если в базе данных есть запись со связанным именем пользователя и паролем, то $query->rowcount(); вернет выбранное количество строк, которое должно быть одним (1) , Условие должно быть

if($count == 1){
  //home-page
}
else{
 //index page
}
30
задан Alnitak 30 April 2009 в 19:00
поделиться

17 ответов

Из библиотеки MSDN для + = :

Использование этого оператора практически совпадает с указанием result = result + expression, за исключением того, что результат оценивается только один раз.

Таким образом, они не являются идентичны, и поэтому x + = 1 будет более эффективным.

Обновление: Я только что заметил, что моя ссылка на библиотеку MSDN была на страницу JScript вместо страницы VB , которая не содержат ту же цитату.

Поэтому при дальнейшем исследовании и тестировании этот ответ не относится к VB.NET. Я ошибался. Вот пример консольного приложения:

Module Module1

Sub Main()
    Dim x = 0
    Console.WriteLine(PlusEqual1(x))
    Console.WriteLine(Add1(x))
    Console.WriteLine(PlusEqual2(x))
    Console.WriteLine(Add2(x))
    Console.ReadLine()
End Sub

Public Function PlusEqual1(ByVal x As Integer) As Integer
    x += 1
    Return x
End Function

Public Function Add1(ByVal x As Integer) As Integer
    x = x + 1
    Return x
End Function

Public Function PlusEqual2(ByVal x As Integer) As Integer
    x += 2
    Return x
End Function

Public Function Add2(ByVal x As Integer) As Integer
    x = x + 2
    Return x
End Function

End Module

IL для PlusEqual1 и Add1 действительно идентичны:

.method public static int32 Add1(int32 x) cil managed
{
.maxstack 2
.locals init (
    [0] int32 Add1)
L_0000: nop 
L_0001: ldarg.0 
L_0002: ldc.i4.1 
L_0003: add.ovf 
L_0004: starg.s x
L_0006: ldarg.0 
L_0007: stloc.0 
L_0008: br.s L_000a
L_000a: ldloc.0 
L_000b: ret 
}

IL для PlusEqual2 и Add2 также практически идентичны:

.method public static int32 Add2(int32 x) cil managed
{ 
.maxstack 2
.locals init (
    [0] int32 Add2)
L_0000: nop 
L_0001: ldarg.0 
L_0002: ldc.i4.2 
L_0003: add.ovf 
L_0004: starg.s x
L_0006: ldarg.0 
L_0007: stloc.0 
L_0008: br.s L_000a
L_000a: ldloc.0 
L_000b: ret 
}
107
ответ дан 27 November 2019 в 22:55
поделиться

If x is a simple integer scalar variable, they should be the same.

If x is a large expression, possibly with side effects, +=1 and ++ should be twice as fast.

Many people concentrate on this kind of low-level optimization as if that's what optimization is all about. I assume you know it's a much bigger subject.

0
ответ дан 27 November 2019 в 22:55
поделиться

Стоит отметить, что + =, - =, * = и т. Д. Выполняют неявное приведение.

int i = 0;
i = i + 5.5; // doesn't compile.
i += 5.5; // compiles.
1
ответ дан 27 November 2019 в 22:55
поделиться

Нет никакой разницы в программной эффективности; просто печатать эффективность.

0
ответ дан 27 November 2019 в 22:55
поделиться

Еще в начале 1980-х годов одна из действительно крутых оптимизаций компилятора Lattice C заключалась в том, что "x = x + 1;", "x + = 1;" и "х ++;" все производится точно такой же машинный код. Если бы они могли это сделать, компилятор, написанный в этом тысячелетии, определенно должен был это сделать.

0
ответ дан 27 November 2019 в 22:55
поделиться

Во время выполнения (по крайней мере, с PERL) нет никакой разницы. x + = 1 примерно на 0,5 секунды быстрее, чем x = x + 1, хотя

0
ответ дан 27 November 2019 в 22:55
поделиться

Они могут быть одинаковыми в VB; они не обязательно одинаковы в C (откуда происходит оператор).

2
ответ дан 27 November 2019 в 22:55
поделиться

Вероятно, оптимизатор выдаст тот же результат, если x является простым типом, таким как int или float

Если бы вы использовали какой-то другой язык (здесь ограниченное знание VB, можете ли вы перегрузить + =?), Где x мог бы быть одним большим сигналяющим объектом, первый создает и дополнительную копию, которая может быть сотнями мегабайт. Последний не делает.

2
ответ дан 27 November 2019 в 22:55
поделиться
  1. Да, они ведут себя одинаково.
  2. Нет, они, вероятно, одинаково эффективны. Оптимизаторы хороши в таких вещах. Если вы хотите перепроверить, напишите оптимизированный код и просмотрите его в отражателе.
2
ответ дан 27 November 2019 в 22:55
поделиться

На x86, если x находится в регистре eax, они оба приведут к чему-то вроде

inc eax;

Так что вы правы, после некоторой стадии компиляции IL будет будь таким же.

Существует целый ряд подобных вопросов, на которые можно ответить «доверься оптимизатору».

Известный миф состоит в том, что
х ++;
менее эффективен, чем
++ х;
потому что он должен хранить временное значение. Если вы никогда не используете временное значение, оптимизатор удалит это хранилище.

4
ответ дан 27 November 2019 в 22:55
поделиться

Так много предположений! Даже вывод с Reflector не обязательно верен, потому что он может выполнять оптимизацию при разборке.

Так почему никто из вас, ребята, просто не заглядывает в код IL? Взгляните на следующую программу на C #:

static void Main(string[] args)
{
    int x = 2;
    int y = 3;
    x += 1;
    y = y + 1;
    Console.WriteLine(x);
    Console.WriteLine(y);
}

Этот фрагмент кода компилируется в:

.method private hidebysig static void Main (string [] args) cil managed
{
.entrypoint
// Размер кода 25 (0x19)
.maxstack 2
.locals init ([0] int32 x,
[1] int32 y)
// здесь некоторые команды опущены

IL_0004: ldloc.0
IL_0005: ldc.i4.1
IL_0006: добавить
IL_0007: stloc.0

IL_0008: ldloc.1
IL_0009: ldc.i4.1
IL_000a: добавить
IL_000b : stloc.1

// некоторые команды здесь опущены
}

Как вы можете видеть, на самом деле это абсолютно то же самое. А почему так? Потому что иль Цель состоит в том, чтобы сказать, что делать, а не как. Оптимизация будет задачей компилятора JIT. Кстати, то же самое в VB.Net

8
ответ дан 27 November 2019 в 22:55
поделиться

ВАЖНО:

Ответы, определяющие оценку, безусловно верны с точки зрения того, что делают + = на общих языках. Но в VB.NET я предполагаю, что X , указанный в OP, является переменной или свойством.


Они, вероятно, будут компилироваться в один и тот же IL.

UPDATE (для устранения вероятного противоречия) :

VB.NET - это спецификация языка программирования. Любой компилятор, который соответствует тому, что определено в спецификации, может быть реализацией VB.NET. Если вы отредактируете исходный код компилятора MS VB.NET, чтобы сгенерировать дрянной код для случая X + = 1 , вы все равно будете соответствовать спецификации VB.NET (поскольку в ней ничего не сказано о том, как это сработает. Он просто говорит, что эффект будет точно таким же, что логично генерировать тот же самый код).

Хотя компилятор очень и очень вероятно (и я чувствую, что это действительно так) генерирует один и тот же код для обоих, но это довольно сложная часть программного обеспечения. Черт возьми, вы даже не можете гарантировать, что компилятор генерирует точно такой же код, когда один и тот же код компилируется дважды!

Что вы можете сказать на 100% безопасно (если вы не знаете исходный код компилятора), это то, что хороший компилятор должен генерировать тот же код с точки зрения производительности , который может или не может быть точно таким же кодом .

11
ответ дан 27 November 2019 в 22:55
поделиться

они компилируются в одно и то же, второй просто набрать.

18
ответ дан 27 November 2019 в 22:55
поделиться

Я написал простое консольное приложение:

static void Main(string[] args)
{
    int i = 0;
    i += 1;
    i = i + 1;
    Console.WriteLine(i);
}

Я разобрал его с помощью Reflector, и вот что я получил:

private static void Main(string[] args)
{
    int i = 0;
    i++;
    i++;
    Console.WriteLine(i);
}

Они одинаковые.

25
ответ дан 27 November 2019 в 22:55
поделиться

одинаковы.

x=x+1 

- математическое противоречие, тогда как

x+=1

- нет, и его легко набирать.

2
ответ дан 27 November 2019 в 22:55
поделиться

Я думал, что различия связаны с дополнительными тактовыми циклами, используемыми для ссылок на память, но я оказался не прав! сам не могу понять эту вещь

instruction type        example                      cycles

======================================== ===========================

ADD reg,reg             add ax,bx                       1
ADD mem,reg             add total, cx                   3
ADD reg,mem             add cx,incr                     2
ADD reg,immed           add bx,6                        1
ADD mem,immed           add pointers[bx][si],6          3
ADD accum,immed         add ax,10                       1

INC reg                 inc bx                          1
INC mem                 inc vpage                       3

MOV reg,reg             mov bp,sp                       1
MOV mem,reg             mov array[di],bx                1
MOV reg,mem             mov bx,pointer                  1
MOV mem,immed           mov [bx],15                     1
MOV reg,immed           mov cx,256                      1
MOV mem,accum           mov total,ax                    1
MOV accum,mem           mov al,string                   1
MOV segreg,reg16        mov ds,ax                       2, 3
MOV segreg,mem16        mov es,psp                      2, 3
MOV reg16,segreg        mov ax,ds                       1
MOV mem16,segreg        mov stack_save,ss               1
MOV reg32,controlreg    mov eax,cr0                     22
                        mov eax,cr2                     12
                        mov eax,cr3                     21, 46
                        mov eax,cr4                     14
MOV controlreg,reg32    mov cr0,eax                     4
MOV reg32,debugreg      mov edx,dr0                     DR0-DR3,DR6,DR7=11;
                                                        DR4,DR5=12 
MOV debugreg,reg32      mov dr0,ecx                     DR0-DR3,DR6,DR7=11;
                                                        DR4,DR5=12 

источник: http://turkish_rational.tripod.com/trdos/pentium.txt

инструкции могут быть переведены как:

;for i = i+1   ; cycles
mov  ax,   [i]  ; 1
add  ax,   1    ; 1
mov  [i],  ax   ; 1

;for i += 1
; dunno the syntax of instruction. it should be the pointers one :S     

;for i++
inc  i          ; 3
;or
mov  ax,   [i]  ; 1
inc  ax         ; 1
mov  [i],  ax   ; 1

;for ++i
mov  ax,   [i]  ; 1
;do  stuff      ; matters not
inc  ax         ; 1
mov  [i],  ax   ; 1

все оказываются одинаковыми: S это просто некоторые данные, которые могут быть полезны. пожалуйста, прокомментируйте!

1
ответ дан 27 November 2019 в 22:55
поделиться

В C ++ это зависит от типа данных x и от того, как определяются операторы. Если x является экземпляром некоторого класса, вы можете получить совершенно разные результаты.

Или, возможно, вам следует исправить вопрос и указать, что x является целым числом или чем-то еще.

1
ответ дан 27 November 2019 в 22:55
поделиться
Другие вопросы по тегам:

Похожие вопросы: